Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I had never seen Hack's pipeline before, which uses an explicit marker ^ to indicate which argument the piped object goes to. This seems like a really cool idea--you can wire functions together any way you want without having to create lambdas. Do any other languages use anything like this?


FYI, you can achieve the same thing with F# pipelines + partial application proposal [1]

  input |> func(?, 2)
  input |> func(1, ?)
While hack's placeholders work exclusively in pipelines, the partial application proposal can be used with any function

  "123"
    .split("")
    .map(parseInt(?)) // make sure radix param is not set

[1] https://github.com/tc39/proposal-partial-application


Mathematica has `f[a,#,b]&`, for example, which is syntactic sugar for `Function[{x}, f[a,x,b]]`, i.e. the function that takes one argument and calls `f` with that argument as the middle parameter and `a, b` as the first and last parameters. It's not quite what you're referring to, but it's similarly an extremely lightweight syntax.


Clojure has the as-> threading macro (probably borrowed from another lisp) where you can specify the placeholder:

  (as-> [:foo :bar] v
    (map name v)
    (first v)
    (.substring v 1))


Tidyr/dplyr (R) can do something very close to this but I don't know how it is achieved. There it is a dot


  y %>% f(x, ., z)  ===  f(x, y, z)
R lets you do macro-ish things at at runtime [1], and `.` is a valid variable name [2]. so %>% can just evaluate the AST of its right argument in an environment with `. = a`.

(it's probably a bit more involved because %>% also supports

  a %>% f(b)  ===  f(a, b)
in which case %>% has to do some AST surgery to splice another argument in front of `b`.)

---

[1] https://en.wikipedia.org/wiki/Fexpr

[2] think `_` in python etc. R uses dots instead of underscores


scala, with its magical underscore. Although it likely desugars to lambdas (or even anonymous classes lol, given how java works)

Actualy this whole debate should be called scala vs F# because they are more corresponding, being both functional language on a OOP runtime.


There is pros/cons to both approaches. The Pipe operator in F# works in conjunction with the HM type inference in the language and static functions often assisting the type checker. i.e. features that work together in a language vs tacked on. F# idiomatic code avoids a lot of virtual dispatch seen in Java/C#, etc as compile time polymorphism is typically how re-use occurs vs objects. I find F# favors compile time abstractions a little more than Scala historically although I note that could be changing.

For most of these proposals it is just syntactic sugar around invoking the function with a placeholder. The pipe in F# is slightly different in that most of the time it has no intermediate lambdas and is compiled in a more performant form. The downside is that unless you allocate that lambda yourself it has to be the last arg. On the plus side like most things in F# it is concise but shows all behavior explicitly - its usually a warning sign if you have to do that and helps reason about performance. Sometimes its a sign that the original function isn't written right or some other inline wrapper could be used for other usages of the function. You can inline a template to rearrange the arg's (inline) to avoid the lambda allocation as well.

This allows some level of re-use and performance benefits avoiding virtual table dispatch and a lambda allocation for many common methods (e.g. map, fold, iter, etc)


> The pipe in F# is slightly different in that most of the time it has no intermediate lambdas and is compiled in a more performant form

I believe the point made in the discussion is that the F# proposal leads to intermediate lambda if the function does not have the right arity. JS also don't do HM so that point is moot.

The people supporting the Hack proposal made the point that their expressions do not desugar to lambda and has no runtime cost, no idea how it works though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: