leostera / caramel

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

Support expression sequences #59

Closed michallepicki closed 3 years ago

michallepicki commented 3 years ago

Describe the bug When combining multiple OCaml expressions with ( expr1 ; expr2 ) or begin expr1 ; expr2 end, the resulting Erlang code is "flattened" and can have different result than expected or not compile at all.

To Reproduce

  1. Create a file main.ml containing
    
    let print thing = Io.format "~0tp~n" [ thing ]

let main _ = print ( print "hej" ; true )

or
```ocaml
let print thing = Io.format "~0tp~n" [ thing ]

let main _ =
  print
    begin
      print "hej" ;
      true
    end
  1. Run command caramel compile main.ml && escript main.erl
  2. See error:
    main.erl:10: function print/2 undefined

This happens because of this incorrect generated Erlang code:

% Source code generated with Caramel.
-module(main).

-export([main/1]).
-export([print/1]).

-spec print(_) -> ok.
print(Thing) -> io:format(<<"~0tp~n">>, [Thing | []]).

-spec main(_) -> ok.
main(_) -> print(print(<<"hej">>),
true).

Expected behavior Erlang gets generated with:

-spec main(_) -> ok.
main(_) -> print(begin print(<<"hej">>), true end).

Environment (please complete the following information):

michallepicki commented 3 years ago

This may be a good point to start: https://github.com/AbstractMachinesLab/caramel/blob/main/caramel/compiler/ocaml_to_erlang/fun.ml#L399

michallepicki commented 3 years ago

I will look into this one

michallepicki commented 3 years ago

With #80 as of e2f88eb we're getting this output:

% Source code generated with Caramel.
-module(main).

-export([main/1]).
-export([print/1]).

-spec print(_) -> ok.
print(Thing) -> io:format(<<"~0tp~n">>, [Thing | []]).

-spec main(_) -> ok.
main(_) -> print(begin
  print(<<"hej">>),
  true
end).

and it runs:

$ caramel compile main.ml
Compiling main.erl      OK
$ escript main.erl
<<"hej">>
true