Comment

Comment by pmontra

    $ irb
    [1, 2, 3, 4].
      select {|n| n % 2 == 0}.
      map {|n| n * n}.
      reduce {|sum, n| sum + n}
    # 20
vs

    $ iex
    [1, 2, 3, 4] \
    |> Enum.filter(fn(n) -> rem(n, 2) == 0 end) \
    |> Enum.map(fn(n) -> n * n end) \
    |> Enum.reduce(0, fn(n, sum) -> sum + n end)
That Ruby code is so compact that I split it on multiple lines only to make the comparison easier.

Even Python is more compact even if it's harder to read because of the reverse order (I'm sure that there is a nested comprehension for that but it's beyond my comprehension skills)

    from functools import reduce
    reduce(lambda x, sum: sum + x, \
    map(lambda x: x * x, \
    filter(lambda x: x % 2 == 0, \
    [1, 2, 3, 4])))
    # 20
The problem here is having to type Module.function(value) vs object.method

OO languages have a more compact notation because objects act as namespaces. Elixir has alias but it doesn't help much and must be used wisely. alias Enum, as: E would only confuse people and gain little.

Then Elixir has too many do end compared to Ruby (coming from Ruby I feel them unnecessary), but that's not a big deal.

Moving from syntax to programming patterns, having to define twice my functions in GenServer (internal API and public API) is too much boilerplate. I'd like to have time to study macros really well and end up with a DryGenServer that lets me def the external API with the internal implementation. Maybe I'll defmacro a defasync and a defsync, that generate the standard "double" GenServer functions.

parent pmontra 9 years ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton