Unexplained "CallFailed" exception when calling constructor function - runtime-error
i have the following method to normalize Java M3 nodes:
public node normalizeNodeDec(ast) {
return top-down visit (ast) {
case \method(x, _, y, z, q) => \method(Type::short(), "methodName", y, z, q)
case \method(x, _, y, z) => \method(Type::short(), "methodName", y, z)
case \parameter(x, _, z) => \parameter(x, "paramName", z)
case \vararg(x, _) => \vararg(x, "varArgName")
case \annotationTypeMember(x, _) => \annotationTypeMember(x, "annonName")
case \annotationTypeMember(x, _, y) => \annotationTypeMember(x, "annonName", y)
case \typeParameter(_, x) => \typeParameter("typeParaName", x)
case \constructor(_, x, y, z) => \constructor("constructorName", x, y, z)
case \interface(_, x, y, z) => \interface("interfaceName", x, y, z)
case \class(_, x, y, z) => \class("className", x, y, z)
case \enumConstant(_, y) => \enumConstant("enumName", y)
case \enumConstant(_, y, z) => \enumConstant("enumName", y, z)
case \methodCall(x, _, z) => \methodCall(x, "methodCall", z)
case \methodCall(x, y, _, z) => \methodCall(x, y, "methodCall", z)
case Type _ => lang::java::jdt::m3::AST::short()
case Modifier _ => lang::java::jdt::m3::AST::\private()
case \simpleName(_) => \simpleName("simpleName")
case \number(_) => \number("1337")
case \variable(x,y) => \variable("variableName",y)
case \variable(x,y,z) => \variable("variableName",y,z)
case \booleanLiteral(_) => \booleanLiteral(true)
case \stringLiteral(_) => \stringLiteral("StringLiteralThingy")
case \characterLiteral(_) => \characterLiteral("q")
}
But when i run this code i get the following error:
Does anyone know what this means and how i can solve this error? I do know that the error points exactly to the line case \method(x, _, y, z, q) => \method(short(), "methodName", y, z, q) and that it highligts q.
I am on rascal stable.
UPDATE: I changed the code accordingly but this still does not seems to solve the error see below:
updated code:
public node normalizeNodeDec(ast) {
return top-down visit (ast) {
case \method(x, _, y, z, q) => \method(Type::short(), "methodName", y, z, q)
case \method(x, _, y, z) => \method(Type::short(), "methodName", y, z)
case \parameter(x, _, z) => \parameter(x, "paramName", z)
case \vararg(x, _) => \vararg(x, "varArgName")
case \annotationTypeMember(x, _) => \annotationTypeMember(x, "annonName")
case \annotationTypeMember(x, _, y) => \annotationTypeMember(x, "annonName", y)
case \typeParameter(_, x) => \typeParameter("typeParaName", x)
case \constructor(_, x, y, z) => \constructor("constructorName", x, y, z)
case \interface(_, x, y, z) => \interface("interfaceName", x, y, z)
case \class(_, x, y, z) => \class("className", x, y, z)
case \enumConstant(_, y) => \enumConstant("enumName", y)
case \enumConstant(_, y, z) => \enumConstant("enumName", y, z)
case \methodCall(x, _, z) => \methodCall(x, "methodCall", z)
case \methodCall(x, y, _, z) => \methodCall(x, y, "methodCall", z)
case Type _ => Type::short()
case Modifier _ => Modifier::\private()
case \simpleName(_) => \simpleName("simpleName")
case \number(_) => \number("1337")
case \variable(x,y) => \variable("variableName",y)
case \variable(x,y,z) => \variable("variableName",y,z)
case \booleanLiteral(_) => \booleanLiteral(true)
case \stringLiteral(_) => \stringLiteral("StringLiteralThingy")
case \characterLiteral(_) => \characterLiteral("q")
}
Updated error:
CallFailed happens when the actual parameter types do not line up with formal parameter types of a function. In this case it's a constructor function which fails to apply because of this.
Unfortunately there is no type-checker in the current stable release to help us realize that there are two version of short() in the current scope, of which silently the "first" one is chosen! There is one from Type and one from TypeSymbol. If it picks the wrong one, you have a match failed because Type and TypeSymbol are incompatible.
To fix, please use: Type::short() for short() and everything should be fine again.
That goes for all instances of types in your code so:
case Type _ => lang::java::jdt::m3::AST::short() should be case Type _ => Type::short() and case Modifier _ => lang::java::jdt::m3::AST::\private() should be case Modifier _ => Modifier::\private()
Related
Meta all introduction in Isabelle
I'm confused about the all introduction meta rule in Isabelle. The papers say it should be: From P deduce ⋀ x. P whenever x is not a free variables in the asumptions. This is confusing to me. I understand better wikipedia's one: From (P y) deduce ⋀ x. P x whenever y is not free in the (implicit) assumptions and x is not free in P. How is the meta-forall rule encoded in Isabelle? Here is the source code: (*Forall introduction. The Free or Var x must not be free in the hypotheses. [x] : A ------ ⋀x. A *) fun forall_intr (ct as Cterm {maxidx = maxidx1, t = x, T, sorts, ...}) (th as Thm (der, {maxidx = maxidx2, shyps, hyps, tpairs, prop, ...})) = let fun result a = Thm (deriv_rule1 (Proofterm.forall_intr_proof x a) der, {cert = join_certificate1 (ct, th), tags = [], maxidx = Int.max (maxidx1, maxidx2), shyps = Sorts.union sorts shyps, hyps = hyps, tpairs = tpairs, prop = Logic.all_const T $ Abs (a, T, abstract_over (x, prop))}); fun check_occs a x ts = if exists (fn t => Logic.occs (x, t)) ts then raise THM ("forall_intr: variable " ^ quote a ^ " free in assumptions", 0, [th]) else (); in (case x of Free (a, _) => (check_occs a x hyps; check_occs a x (terms_of_tpairs tpairs); result a) | Var ((a, _), _) => (check_occs a x (terms_of_tpairs tpairs); result a) | _ => raise THM ("forall_intr: not a variable", 0, [th])) end; Suppose I am a mathematician with only some notions of programming. How would you convince me the piece of code below implements the meta-forall rule in a sensible manner?.
Flow: annotation of a function variable
What is a proper flow type annotations of variable const a = x => x using generics? const a: (<T> T => T) = x => x is failing.
Flow implicitly types expression x => x as (mixed) => mixed (according to flow type-at-pos). Thus the problem with const a: (<T> T => T) = x => x // failing is that type of right-hand side ((mixed) => mixed) doesn't match to type of left-hand side (<T> (T) => T). Possible solution could be to explicitly set type of right-hand side: const a: (<T> (T) => T) = <U> (x: U): U => x If use of generic wouldn't be required, annotated definition of a could look like: const a: (mixed) => mixed = x => x
Changing to Tail Recursive SML
Ok, so I'm trying to change this function into Tail Recursive. The Definition I have of Tail Recursive is to use a "Local Helper Function" to accumulate my answer and return it without calling the primary function recursively. these functions work properly. fun same_string(s1 : string, s2 : string) = s1 = s2 fun all_except_option (name, []) = NONE | all_except_option (name, x::xs)= case same_string (x , name) of true => SOME xs | false => case all_except_option(name,xs) of NONE => NONE | SOME z => SOME(x::z) fun get_substitutions1 ([],name2) = [] (*get_substitutions2 is same but tail recursive *) | get_substitutions1 (x::xs,name2) = case all_except_option (name2,x) of NONE => get_substitutions1 (xs,name2) | SOME z => z # get_substitutions1(xs,name2) So here are my attempts at tail recursion which do not work and I think I am missing something fairly basic that I am overlooking due to my lack of experience in SML. fun get_substitutions2 (lst,name3) = let fun aux (xs,acc) = case all_except_option(name3,x::xs) of NONE => aux(xs, acc) | SOME z => aux(xs, z::acc) in aux(lst,[]) end and fun get_substitutions2 (lst,name3) = let fun aux (xs,acc) = case all_except_option(name3,x::xs) of NONE => aux(xs, acc) | SOME z => aux(xs, z#acc) in aux(lst,[""]) end Both "get_substitutions" functions are supposed to do the same thing. compare String1 to string list list, return single list made up of all lists containing String1 minus String1. My attempts at using Tail Recursion have resulted in the following error. Error: unbound variable or constructor: x uncaught exception Error raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27 ../compiler/TopLevel/interact/evalloop.sml:44.55 ../compiler/TopLevel/interact/evalloop.sml:296.17- Here are a few examples of calling get_substitutions2: get_substitutions2 ([["foo"],["there"]], "foo"); (* = [] *) get_substitutions2 ([["fred","fredrick","freddie","F","freddy"],["Will","William","Willy","Bill"]],"Bill"); (* = ["Will","William","Willy"] *) get_substitutions2 ([["a","b"],["a","c"],["x","y"]], "a"); (* = ["c","b"] *)
You need to use the same patterns you had for get_substitutions1 in your aux function definition: fun get_substitutions2 (lst,name3) = let fun aux ([],acc) = acc (* BASE CASE *) | aux (x::xs,acc) = (* BINDING x IN PATTERN *) case all_except_option(name3,x) of NONE => aux(xs, acc) | SOME z => aux(xs, z#acc) in aux(lst,[]) end
SML Sum of List using option and Pattern matching
I'm creating sum of list and using option in it. When I pass an empty list, I should get NONE or else SOME value. I'm able to do that in the following way: fun sum_list xs = case xs of [] => NONE | x => let fun slist x = case x of [] => 0 | x::xs' => x + slist xs' in SOME (slist x) end But I want to do it in the other way round using pattern matching, in which I want to eval the result of sum_list to see whether it is NONE or contains some other value. I have tried in various ways but I cannot get a hang of how to do in that way.
I think what you currently have is very clear and easy to understand. If you want to avoid using slist, you have to call sum_list recursively on the tail of the list, pattern-match on that option value and return appropriate results: fun sum_list xs = case xs of [] => NONE | x::xs' => (case (sum_list xs') of NONE => SOME x | SOME y => SOME (x+y))
Case Statements and Pattern Matching
I'm coding in SML for an assignment and I've done a few practice problems and I feel like I'm missing something- I feel like I'm using too many case statements. Here's what I'm doing and the problem statements for what I'm having trouble with.: Write a function all_except_option, which takes a string and a string list. Return NONE if the string is not in the list, else return SOME lst where lst is like the argument list except the string is not in it. fun all_except_option(str : string, lst : string list) = case lst of [] => NONE | x::xs => case same_string(x, str) of true => SOME xs | false => case all_except_option(str, xs) of NONE => NONE | SOME y=> SOME (x::y) Write a function get_substitutions1, which takes a string list list (a list of list of strings, the substitutions) and a string s and returns a string list. The result has all the strings that are in some list in substitutions that also has s, but s itself should not be in the result. fun get_substitutions1(lst : string list list, s : string) = case lst of [] => [] | x::xs => case all_except_option(s, x) of NONE => get_substitutions1(xs, s) | SOME y => y # get_substitutions1(xs, s) - same_string is a provided function, fun same_string(s1 : string, s2 : string) = s1 = s2
First of all I would start using pattern matching in the function definition instead of having a "top-level" case statement. Its basically boils down to the same thing after de-sugaring. Also I would get rid of the explicit type annotations, unless strictly needed: fun all_except_option (str, []) = NONE | all_except_option (str, x :: xs) = case same_string(x, str) of true => SOME xs | false => case all_except_option(str, xs) of NONE => NONE | SOME y => SOME (x::y) fun get_substitutions1 ([], s) = [] | get_substitutions1 (x :: xs, s) = case all_except_option(s, x) of NONE => get_substitutions1(xs, s) | SOME y => y # get_substitutions1(xs, s) If speed is not of importance, then you could merge the two cases in the first function: fun all_except_option (str, []) = NONE | all_except_option (str, x :: xs) = case (same_string(x, str), all_except_option(str, xs)) of (true, _) => SOME xs | (false, NONE) => NONE | (false, SOME y) => SOME (x::y) But since you are using append (#), in the second function, and since it is not tail recursive, I don't believe that it your major concern. Keep in mind that append is potential "evil" and you should almost always use concatenation (and then reverse your result when returning it) and tail recursion when possible (it always is). If you really like the explicit type annotations, then you could do it like this: val rec all_except_option : string * string list -> string list option = fn (str, []) => NONE | (str, x :: xs) => case (same_string(x, str), all_except_option(str, xs)) of (true, _) => SOME xs | (false, NONE) => NONE | (false, SOME y) => SOME (x::y) val rec get_substitutions1 : string list list * string -> string list = fn ([], s) => [] | (x :: xs, s) => case all_except_option(s, x) of NONE => get_substitutions1(xs, s) | SOME y => y # get_substitutions1(xs, s) But that is just my preferred way, if I really have to add type annotations. By the way, why on earth do you have the same_string function? You can just do the comparison directly instead. Using an auxilary function is just wierd, unless you plan to exchange it with some special logic at some point. However your function names doesn't sugest that.
In addition to what Jesper.Reenberg mentioned, I just wanted to mention that a match on a bool for true and false can be replaced with an if-then-else. However, some people consider if-then-else uglier than a case statement
fun same_string( s1: string, s2: string ) = if String.compare( s1, s2 ) = EQUAL then true else false fun contains( [], s: string ) = false | contains( h::t, s: string ) = if same_string( s, h ) then true else contains( t, s ) fun all_except_option_successfully( s: string, [] ) = [] | all_except_option_successfully( s: string, h::t ) = if same_string( s, h ) then t else ( h :: all_except_option_successfully( s, t ) ) fun all_except_option( s: string, [] ) = NONE | all_except_option( s: string, h::t ) = if same_string( s, h ) then SOME t else if contains( t, s ) then SOME ( h :: all_except_option_successfully( s, t ) ) else NONE