Hacker News new | past | comments | ask | show | jobs | submit login

Subjectively, the chief advantage is readability for long chains of function composition. Compare list.fft.map(square).sum.sqrt to sqrt(sum(map(fft(list), square))). This is all a matter of taste, but IMO the former reads more easily.

It's a pretty trivial matter, so I wouldn't go breaking encapsulation everywhere just to support it. D has a feature called Universal Function Call Syntax where a.f(b, c) is sugar for f(a, b, c) for any free function, rendering those issues moot. I just wish more languages would pick it up!




Why not this? (sqrt . sum . map square . fft) list

I really don't see what chaining via methods bring that simple function composition doesn't.


> I really don’t see what chaining via methods bring that simple function composition doesn’t.

Visual flow from input to output.

(Ruby can compose either way, so you can build a pipeline of procs in flow order, but if you aren’t chaining the input still goes at the end, not the beginning.)


That's not possible to write in most languages. If a language does support compose operator or custom operators then yes I think that style is good too. But there is no way to write that style in python/ruby.

My ideal preference is for a language to support universal function call syntax where x.f(y) is equivalent to f(x,y) always and also include support for custom operators (or at least include common functional operators).


> That’s not possible to write in most languages. If a language does support compose operator or custom operators then yes I think that style is good too. But there is no way to write that style in python/ruby.

Ruby has composition operators in both directions:

given:

  x = 2
  f = lambda {|a| a+1}
  g = lambda {|a| a*2}
the following are all equivalent:

  f[g[x]]
  (f>>g)[x]
  (g<<f)[x]
What’s inconvenient is that to use it with methods, even ones that can be invoked in ways that look like function calls in other languages, you have to realize a method object, since method names don’t name objects. Or, as Matz says (I don’t think of Ruby as a Lisp at all, but in this context it makes sense) Ruby is a Lisp-2, not a Lisp-1.


Those square parentheses are unfortunate because traditionally they are used to index arrays. I'd like to write one of

  2.g.f
  g(2).f
  (g >> f)(2)
  (f << g)(2)
with a strong preference for the first one. That's the Elixir pipeline with a dot instead of a |>

The second one is OK-ish but it turns weird with a long list of functions.

The last ones are not nice to read, too much syntactical overhead.

There is a ton of new syntax added to Ruby in the last years and they had to find a way to fit it into the space between what was already there. The results are not always nice IMHO.


> Those square parentheses are unfortunate because traditionally they are used to index arrays.

They’ve been among the methods for invoking procs since at least Ruby 1.8 (2003); there are several – all of these are equivalent.

  f[x]
  f.(x)
  f.call(x)
  f.yield(x)
> I’d like to write one of:

  2.g.f
  g(2).f
  (g >> f)(2)
  (f << g)(2)
Ruby is a pure OOP language, and “.” is the syntax for method invocation. So its really not available as a composition operator. So the first two don’t work for that reason. Further extending Ruby’s syntax to make unmodified parens both invoke methods and serve as syntax sugar for .call() on objects would probably be problematic (that’s why “.()” was adopted.)

> There is a ton of new syntax added to Ruby in the last years

None of the stuff related to this except the composition operators is added recently. And those aren’t really syntax, just normal operator methods added to the Proc class.


Passing other parameters into the composed functions.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: