leostera / caramel

:candy: a functional language for building type-safe, scalable, and maintainable applications
https://caramel.run
Apache License 2.0
1.06k stars 25 forks source link

fix(compiler): better function and arity detection #89

Closed michallepicki closed 3 years ago

michallepicki commented 3 years ago

closes #70

michallepicki commented 3 years ago

Tests are passing now, we could add some refactors.

michallepicki commented 3 years ago

@ostera no time today on my end I'm afraid, we could merge and clean up later if you want, I kind of hacked this together but don't fully understand all the code yet but I'm getting there

michallepicki commented 3 years ago

@ostera I added code to skip through the Tlinks when computing arity but it broke let rec declarations taking just () argument:

$ make test
dune runtest ./erlang/tests -p erlang
dune runtest ./tests -p caramel
Done: 253/256 (jobs: 2)File "tests/compiler/expressions.t/run.t", line 1, characters 0-0:
         git (internal) (exit 1)
(cd _build/.sandbox/cceca0164aec5e38ffd9edb1020faed3/default && /usr/bin/git --no-pager diff --no-index --color=always -u ../../../default/tests/compiler/expressions.t/run.t tests/compiler/expressions.t/run.t.corrected)
diff --git a/../../../default/tests/compiler/expressions.t/run.t b/tests/compiler/expressions.t/run.t.corrected
index 2b033f9..45a9c2d 100644
--- a/../../../default/tests/compiler/expressions.t/run.t
+++ b/tests/compiler/expressions.t/run.t.corrected
@@ -152,7 +152,7 @@
   f(G) -> G().

   -spec g() -> _.
-  g(_) -> f(fun g/0).
+  g(_) -> f(fun g/1).

   -spec add(integer(), integer()) -> integer().
   add(X, Y) -> erlang:'+'(X, Y).
@@ -438,7 +438,7 @@
   -spec run_local() -> atom
          .
   run_local() ->
-    X = fun run_local/0,
+    X = fun run_local/1,
     Y = atom,
     Y.

Makefile:37: recipe for target 'test' failed
make: *** [test] Error 1

Do you know where I should look to fix those?

michallepicki commented 3 years ago

Or maybe this is the correct place to detect 1 argument functions that take just () and convert them to 0 argument erlang functions 🤔 And previously these examples were just working because of the default 0 returned

michallepicki commented 3 years ago
let f g = g ()
let rec g _ = f g

Is this just an infinite recursion loop? :D The spec for g prints no arguments but function head still prints the _ even though it only type checks with (), maybe that's another issue here (see first diff in comment above)

michallepicki commented 3 years ago

@ostera I re-read the code you linked and understood that it will probably do what I need, so I re-used it, and removed some leftover (hopefully dead) code. When the tests pass I think this will be ready to go! 🚀