# \[Solved\] Piping into constructors

**URL:** <https://discuss.ocaml.org/t/solved-piping-into-constructors/560>\
**Category:** Learning\
**Created:** [July 18, 2017, 3:39am UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560 "2017-07-18T03:39:06Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)\
**Post date:** [July 18, 2017, 3:39am UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/1 "2017-07-18T03:39:06Z")

</div>

I often write code that uses pipes, and sometimes have constructors on the end of those pipes:

```auto
type val = DInt of int

let myfunc : val = 5 |> DInt

```

This was all well and good when I was using Oasis. When I try to use jbuilder to build instead, I get this error:

```auto
Error: The constructor DInt expects 1 argument(s),
       but is applied here to 0 argument(s)

```

If I amend my code to:

```auto
let myfunc = DInt 5

```

then everything works great.

Since I like to pipe into constructors and was very happy doing it, my question is this: what was oasis doing that allowed me do that, that jbuilder does not?

This was my \_oasis file:

```auto
Name: ConstructorWeirdness
Version: 0.1
License: PROP

OASISFormat: 0.4
BuildTools: ocamlbuild
Plugins: DevFiles (0.4)

Executable "constructorWeirdness"
  Path: src
  MainIs: main.ml
  BuildDepends:
    cohttp.lwt,
    yojson,
    core,
    ppx_jane,
    threads,
    postgresql

  # use byte because osx wants us to click a button every time
  CompiledObject: byte

```

Here’s my jbuild:

```auto
(jbuild_version 1)

(executable
  ((name main)
    (public_name main)
    (libraries (core cohttp.lwt yojson threads ppx_jane postgresql))))

```

Any thoughts? Thanks!

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [July 18, 2017, 8:28am UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/2 "2017-07-18T08:28:31Z")

</div>

> [@pbiggar](#):
>
> Since I like to pipe into constructors and was very happy doing it, my question is this: what was oasis doing that allowed me do that, that jbuilder does not?

I suspect you will not be able to reproduce this. In OCaml constructors are not functions.

(Also please be careful not to abuse the pipe operator it sometimes make code more obscure than enlighting)

---

<div class="post-metadata">

**Author:** ![ashish](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ashish/32/34_2.png) [@ashish](https://discuss.ocaml.org/u/ashish)\
**Post date:** [July 18, 2017, 1:26pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/3 "2017-07-18T13:26:21Z")

</div>

I don’t see how your code could have compiled. There are at least two errors: `val` is a keyword and OCaml doesn’t allow constructors to be used as functions. Your build tool wouldn’t matter here.

---

<div class="post-metadata">

**Author:** ![smolkaj](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/smolkaj/32/266_2.png) [@smolkaj](https://discuss.ocaml.org/u/smolkaj)\
**Post date:** [July 18, 2017, 1:39pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/4 "2017-07-18T13:39:41Z")

</div>

The reason is that your oasis setup applies the ppx rewriter `ppx_jane`, whereas your jbuild setup does not. Let me explain the details:

The package `ppx_jane` bundles up a bunch of ppx rewriters, one of which is [`ppx_pipepang`](https://github.com/janestreet/ppx_pipebang). This rewriter syntactically replaces `x |> f` with `f x`. As a result, the line

```auto
let myfunc : val = 5 |> DInt

```

gets rewritten to

```auto
let myfunc : val = DInt 5

```

which is valid OCaml (forgetting for a moment that `val` is a keyword).

In your oasis setup, `ppx_jane` is handled correctly, thus the rewrite gets applied and compilation succeeds.  
In your jbuilder setup however, you include `ppx_jane` as a library (rather than a ppx rewriter), and so the rewrite never happens. Thus compilation fails, because `5 |> DInt` is not valid OCaml (since constructors are not functions in OCaml).

As an aside, the fact that constructors are not first class citizens in OCaml is somewhat annoying and doesn’t have any conceptual reasons. As far as I know, it’s a design choice to simplify the implementation / improve performance.

---

<div class="post-metadata">

**Author:** ![ashish](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ashish/32/34_2.png) [@ashish](https://discuss.ocaml.org/u/ashish)\
**Post date:** [July 18, 2017, 1:57pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/5 "2017-07-18T13:57:11Z")

</div>

> [@smolkaj](#):
>
> ppx\_pipepang

Thanks for pointing out this package. I didn’t recall it. What’s the point of this? I vaguely recall there was some performance hit when using `|>`. Is that the reason?

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [July 18, 2017, 4:11pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/6 "2017-07-18T16:11:08Z")

</div>

> [@smolkaj](#):
>
> As far as I know, it’s a design choice to simplify the implementation / improve performance.

From what I remember of the explanation, it wasn’t even for performance. In fact, it existed in OCaml’s predecessor, caml-light. The feature simply didn’t seem useful enough to the designers to include it in OCaml, which in retrospect seems really odd. Not only that, it’s near-impossible to insert this feature in a backwards-compatible way, which means OCaml is most likely never going to have it.

---

<div class="post-metadata">

**Author:** ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)\
**Post date:** [July 18, 2017, 5:00pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/7 "2017-07-18T17:00:22Z")

</div>

Thanks @smolkaj, that did indeed pix it!

Here’s the jbuild file that works:

```auto
(jbuild_version 1)

(executable
  (
    (name dark)
    (public_name dark)
    (modes (byte))
    (libraries (core cohttp.lwt yojson threads postgresql))
    (preprocess (pps (ppx_jane)))
  )
)

```

---

<div class="post-metadata">

**Author:** ![Leonidas](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/leonidas/32/4039_2.png) [@Leonidas](https://discuss.ocaml.org/u/Leonidas)\
**Post date:** [July 18, 2017, 6:30pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/8 "2017-07-18T18:30:33Z")

</div>

That said, while I absolutely love constructors as functions, I’d be wary of using a ppx rewriter which subtly changes the semantics of the code in a very surprising way. Maybe it would be better to use a deriving plugin which generates functions for constructors and then has the regular OCaml semantics?

---

<div class="post-metadata">

**Author:** ![smolkaj](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/smolkaj/32/266_2.png) [@smolkaj](https://discuss.ocaml.org/u/smolkaj)\
**Post date:** [July 19, 2017, 2:11am UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/9 "2017-07-19T02:11:51Z")

</div>

Unfortunately, you cannot define functions that begin with an uppercase letter (and thus, have the same syntax as constructors) in OCaml. If you’re happy with lowercase first-class constructors, [ppx\_variants\_conv](https://github.com/janestreet/ppx_variants_conv) can derive them for you automatically.

Again, there is nothing deep here. Morally, constructors should be functions, and they are in more academic functional languages such as Standard ML or Haskell. OCaml is a more pragmatic language, and it’s willing to sacrifice strict mathematical aesthetics here and there if it allows for better performance / convenience. IMHO, that’s also what makes it a much more usable language than Standard ML and others, so I can live with it even though the lack of first class constructors is ugly.

EDIT: That said, I would be curious to hear what the rational behind this design choice was. I cannot believe it wasn’t thought to be useful – who wouldn’t appreciate being able to write `List.map ~f:Some`, for example?

---

<div class="post-metadata">

**Author:** ![rizo](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/rizo/32/93_2.png) [@rizo](https://discuss.ocaml.org/u/rizo)\
**Post date:** [July 20, 2017, 12:51pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/10 "2017-07-20T12:51:32Z")

</div>

> From what I remember of the explanation, it wasn’t even for performance. In fact, it existed in OCaml’s predecessor, caml-light. The feature simply didn’t seem useful enough to the designers to include it in OCaml, which in retrospect seems really odd. Not only that, it’s near-impossible to insert this feature in a backwards-compatible way, which means OCaml is most likely never going to have it.

Do you have any idea what changes to the compiler would be necessary to introduce to make constructors functions?

---

<div class="post-metadata">

**Author:** ![ashish](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ashish/32/34_2.png) [@ashish](https://discuss.ocaml.org/u/ashish)\
**Post date:** [July 20, 2017, 1:06pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/11 "2017-07-20T13:06:38Z")

</div>

Xavier Leroy provided his view on constructors as functions in this old email thread:  
[http://caml.inria.fr/pub/ml-archives/caml-list/2001/08/47db53a4b42529708647c9e81183598b.en.html](http://caml.inria.fr/pub/ml-archives/caml-list/2001/08/47db53a4b42529708647c9e81183598b.en.html)

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [July 20, 2017, 2:05pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/12 "2017-07-20T14:05:08Z")

</div>

Thanks for finding that. As I remembered, the reasoning was weak. I misremembered that caml-light had curried constructors, though.

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [July 20, 2017, 2:25pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/13 "2017-07-20T14:25:11Z")

</div>

The problem is one of syntax. Since we currently require parentheses to accept multiple arguments, we can’t just switch to accepting curried arguments instead. It would have to be a switch like -safe-string, and many core devs aren’t satisfied with that transition yet, and wouldn’t want to start a new one. Also, trying to support both syntaxes at the same time (parentheses and currying) gets really hairy, especially since we allow dropping the parentheses for a single argument.

---

<div class="post-metadata">

**Author:** ![smolkaj](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/smolkaj/32/266_2.png) [@smolkaj](https://discuss.ocaml.org/u/smolkaj)\
**Post date:** [July 20, 2017, 2:56pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/14 "2017-07-20T14:56:31Z")

</div>

Seems to me that the issue is really with the definition of constructors. If the syntax were

```auto
type t =
  | C1 : int -> int -> t
  | C2 : int*int -> t  

```

then Xavier’s second point would disappear.

---

<div class="post-metadata">

**Author:** ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)\
**Post date:** [July 20, 2017, 6:19pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/15 "2017-07-20T18:19:28Z")

</div>

You’re intruding on GADT territory with this syntax, and I’m not experienced enough to comment on this. It bears remembering that constructors aren’t just construction functions – they’re also used to destruct and pattern match, and I’m not sure how pattern matching would work with your example. Also,

```
type t =
    | C1 of int * int
    | C2 of (int * int)

```

aren’t the same. The first is a constructor of 2 numbers, while the second is a constructor that takes a pair. It makes more sense to me to make the first one curriable in the language, but that would require a radical change.

---

<div class="post-metadata">

**Author:** ![smolkaj](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/smolkaj/32/266_2.png) [@smolkaj](https://discuss.ocaml.org/u/smolkaj)\
**Post date:** [July 20, 2017, 8:31pm UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/16 "2017-07-20T20:31:24Z")

</div>

The metatheory behind algebraic data types is well-studied in the programming language literature and well-understood. What I’m proposing here has nothing to do with GADTs, I’m just proposing a different syntax for algebraic datatypes. (By the way, it’s not my invention, it’s standard for example in the Coq proof assistant.)

That said, the same syntax can be used to define GADTs, too. That’s another reason why the syntax is nice: things are more uniform that way, and it becomes clear syntactically that algebraic data types are indeed just a subset of the generalized algebraic data types.

You’re example gets exactly to my point. The `int * int` in `C1 of int * int` is not a tuple type, but syntactically it looks like one. With the GADT syntax, the difference between `C1` and `C2` becomes obvious and explicit. And no one would expect `C2` to be curried with that syntax.

---

<div class="post-metadata">

**Author:** ![cfcs](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cfcs/32/833_2.png) [@cfcs](https://discuss.ocaml.org/u/cfcs)\
**Post date:** [November 5, 2017, 3:36am UTC](https://discuss.ocaml.org/t/solved-piping-into-constructors/560/17 "2017-11-05T03:36:09Z")

</div>

FWIW there’s also `ppx_curried_constr` that aims to provide this feature.

EDIT: sorry to bump this thread, I didn’t notice the date.
