caramel
caramel copied to clipboard
Pipe operator support
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
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 https://github.com/AbstractMachinesLab/caramel/issues/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!
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.
@ostera I would love to implement this!
@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 🙌🏽