Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Recursive function definition raises error #53

Open
sebastien opened this issue Dec 29, 2018 · 3 comments
Open

Recursive function definition raises error #53

sebastien opened this issue Dec 29, 2018 · 3 comments

Comments

@sebastien
Copy link

It seems that curv currently does not allow recursive function definition (see group thread). The following code

rand1 =  match [
    (x)   ->  frac(sin(x)*100000.0);
    (x,y) -> rand1(rand1(x) + rand1(y));
];

raises the following error:

ERROR: illegal recursive reference
at file "letrec.curv":
3|     (x,y) -> rand1(rand1(x) + rand1(y));
                ^^^^^          
@doug-moen
Copy link
Member

Curv only supports recursive function definitions, not recursive data definitions. The 'illegal recursive reference' error is reported early in compilation: it happens while resolving names, before all identifiers have been looked up.

A definition like this causes an error, because it looks like a recursive data definition to the compiler:

rand1 =  f [
    (x)   ->  frac(sin(x)*100000.0);
    (x,y) -> rand1(rand1(x) + rand1(y));
];

If the compiler somehow knew that f is a function that returns another function during this phase of compilation, then it could treat this as a recursive function definition and generate the appropriate code. But it is not smart enough to do that. And match is just an ordinary function, it is not a keyword or special syntax, so the same problem happens if you replace f with match.

Until this is fixed, the workaround is to write:

rand1 x = x >> match [
    (x)   ->  frac(sin(x)*100000.0);
    (x,y) -> rand1(rand1(x) + rand1(y));
];

@doug-moen
Copy link
Member

One way to attack this problem is to introduce special syntax for defining 'overloaded' functions. The following syntax is copied from Haskell.

  rand1 (x :: is_num) = frac(sin(x)*100000.0);
  rand1 (x, y) = rand1(rand1(x) + rand1(y));

It will be easier for the compiler to recognize that rand1 is a function using this syntax. Plus, the code is shorter and easier to write.

@sebastien
Copy link
Author

Yes, that's also what Prolog or Erlang do, and it will be consistent with the let..in pattern assignment (ie let (x,y)=(1,0)).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants