I am trying to work some with generic types in Rascal using the &T
concept. There are some things I am finding a bit odd though. It's unclear to me why something like the following won't work:
private tuple[str,int] synthesise_p(Fancy::AST::Exp exp, int count) {
switch (exp) {
case &T n(&T e0, &T e1, &T e2): {
println("e0: <e0> typeOf(e0): <typeOf(e0)>\ne1: <e1> typeOf(e1): <typeOf(e1)>\ne2: <e2> typeOf(e2): <typeOf(e2)>\n");
for (ty <- e0) {
println("ty: <ty>");
}
}
}
}
When I print e0
, e1
and e2
:
e0: ["x"] typeOf(e0): list(str()
e1: [nat(1),nat(2)] typeOf(e1): list(adt("Exp",[]))
e2: nat(3) typeOf(e2): adt("Exp",[])
With the following error:
|rascal://Synth::Synthesiser|(2291,2,<81,23>,<81,25>): value is not enumerable
?[Advice](http://tutor.rascal-mpl.org/Errors/Static/NotEnumerable/NotEnumerable.html)
What I would really like to do is be able to iterate over e0
and e1
and extract the types of each element in those lists.
What am I missing / doing wrong?
Thanks!
The principle of rascals type system is that it is static. This may be confusing since we have not released the static checker yet, but the interpreter currently simulates the static type system because we have been planning all along to have a statically typed language.
Concretely this means that the type variables you use in patterns which are used inside of the bodies of functions are statically bound to their upper bound, in your case: value. This then is not an enumerable type which is why the implementation of <- complains. If you want to match that it requires a more concrete type such as list[value] or list[&T], equivalently.
As an aside, a way to bind type parameters to more concrete types is by using them in function headers. The static types off the actual parameters will then be used. Another way is to use a named constructor with a visible declaration in a pattern such that the argument positions can be matched respectively to the type arguments. This is not very useful though since if you know the declaration there is no need to infer a type either.
The typeOf function returns the dynamic type of a value, which explains why your prints work as reported.
Does this answer your question with enough detail?