Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipe operator support #72

Open
michallepicki opened this issue Mar 5, 2021 · 4 comments
Open

Pipe operator support #72

michallepicki opened this issue Mar 5, 2021 · 4 comments
Labels
compiler Related to the OCaml to Erlang compiler enhancement New feature or request

Comments

@michallepicki
Copy link
Contributor

michallepicki commented Mar 5, 2021

It would be great to have support for the pipe operator. It is a common way in many functional programming languages to compose functions into a readable left-to-right or top-to-bottom "pipeline" of steps of computation.

Documentation in OCaml stdlib
Documentation in Elixir Kernel

I think it should probably behave like in OCaml and not like Elixir, meaning this Caramel code in file main.ml when ran with ocaml compile main.ml && escript main.erl would print 2 (notice the order of arguments in subtract and divide):

let print_int number = Io.format "~0tp~n" [ number ]

let subtract x y = y - x
let main _ =
  let divide x y = y / x in
  10 |> subtract 2 |> divide 4 |> print_int

so it would be equivalent to this Caramel code:

let print_int number = Io.format "~0tp~n" [ number ]

let subtract x y = y - x
let main _ =
  let divide x y = y / x in
  print_int (divide 4 (subtract 2 10))

and behave the same as this toplevel OCaml code:

(* let print_int number = Io.format "~0tp~n" [ number ] *)

let subtract x y = y - x ;;
let main _ =
  let divide x y = y / x in
  10 |> subtract 2 |> divide 4 |> print_int ;;

main ()

when executed:

$ ocaml main.ml
2
@michallepicki
Copy link
Contributor Author

michallepicki commented Mar 5, 2021

The easiest way to make it work right now I think, would be to make the partial function application compile to anonymous functions first (tracked in #44) and then introduce a pipe function in caramel_runtime that this operator could compile to, which would take an argument and a function, and it would apply the argument to that function. It still wouldn't work when running with the escript example from above, and it would be unreasonably slow, but I think at least it might work!

@leostera
Copy link
Owner

leostera commented Mar 5, 2021

I agree that I'd expect this to behave like in OCaml. I also think that I should bring up that ReScript and Reason chose to favor "pipe first" (->) instead, which behaves just like Elixir's pipe, because it was said that it type inference with records was better.

I haven't really experienced any problems with |> that I can recall right now, to be honest, just felt that I should bring this up.

@leostera leostera added compiler Related to the OCaml to Erlang compiler enhancement New feature or request labels Mar 5, 2021
@ayshiff
Copy link

ayshiff commented Mar 26, 2021

@Ostera I would love to implement this!

@leostera
Copy link
Owner

@ayshiff dope! 🚀 the easiest would be to expose (|>) as an external that maps to a caramel_runtime:pipe/2 function somewhere.

But feel free to give it an initial stab by just hacking around the compiler, and we can then refine it 🙌🏽

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Related to the OCaml to Erlang compiler enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants