Pipeline-firendly variable assignment

450 views
Skip to first unread message

Filip Haglund

unread,
Jan 1, 2017, 6:01:45 PM1/1/17
to elixir-lang-core
I love the flow of how pipelines read top-down as a series of steps, but there's something I don't like about it; having to look back at the start of the pipeline again to see in what variable the result is stored. It's an uncanny valley; reading functional code top-down is really clear and easy, but having to jump back up every now and then feels like when developers extract single-use functions that really should've stayed inline. It's a readibility issue.

I wish the assignment was at the end of the pipeline instead. Equality could've worked, but doesn't, since it handles left and right arguments differently (illegal pattern, otherwise it'd be great to just put the variable assignment at the end, `= b`). 

Here's a macro that kinda simulates how it would work.

defmacro into(a, b) do
 
{:=, [line: 1], [b, a]}
end

Intended demo-usage:

|> (into b)


I'd prefer something like `|=>` in place of a pipe

a
|> fn1
|> fn2
|=> b

but this is just a macro right now.


What do you think?

José Valim

unread,
Jan 1, 2017, 6:13:57 PM1/1/17
to elixir-l...@googlegroups.com
Pipe extensions to the language are proposed somewhat frequently. The answer is almost always the same: making the pipe more complex detracts from its main feature: simplicity. If we had adopted every proposed pipe operator so far, we would certainly have more than a handful of them.

Other than that, I think using pipes for a lexical side-effect is confusing, especially because pipes put focus on data transformations (rather than data mutation or even scope mutation).

Thanks for the first proposal of the year and happy new year!

José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/1b11f727-fd6a-4467-8754-5eb4649c432c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tallak Tveide

unread,
Jan 2, 2017, 1:24:08 PM1/2/17
to elixir-lang-core
I had the same thought some time ago, with a code to prove the possibility.

I have since decided it's a bad idea.

There are many ways to extend Elixir 'irresponsbly' making code that is not clear and readable like core Elixir is. So by adding features like extended pipes and iteratable tuples (both interesting in isolation), we discover that actually 'less is more'

For reference: https://gist.github.com/tallakt/a6701b1e5c2808c85104

See the test at the end for usage example

Wiebe-Marten Wijnja

unread,
Jan 2, 2017, 4:24:35 PM1/2/17
to elixir-lang-core
Assignments with pipelines are often a great indication that a function can be refactored.

For instance, if you have a function like follows:

def myfun(x, y) do
  a
=
  x
 
|> fun_1
 
|> fun_2

  b
=
  y
 
|> fun_3
 
|> fun_4

 
# now do something with a and b, e.g.:
 
%myStruct{foo: a * b}
end



then this is a great indication that this function can be refactored to something like:

def myfun(x, y) do
  a 
= subfun(x)
  b 
= subfun_b(y)
  
# now do something with a and b, e.g.: 
  
%myStruct{foo: a * b}
end

defp subfun_a(x) do
  x
  |> fun_1
  |> fun_2
end

defp subfun_b(y) do
  y
  |> fun_3
  |> fun_4
end

I believe this is approach is at least as clean as this proposal, without needing new syntax. :-)
Reply all
Reply to author
Forward
0 new messages