Proposal: Downward Assignments(bugs.ruby-lang.org)
bugs.ruby-lang.org
Proposal: Downward Assignments
https://bugs.ruby-lang.org/issues/17768
28 comments
This is hilarious, and clearly a joke, but it does make one think. I've always thought that it would be nice to have variables which you don't name, which only live over a couple of lines, where it's clear the variable is just for some plumbing and doesn't need a name. I wonder if there is actually something in these two concepts combined
> I've always thought that it would be nice to have variables which you don't name, which only live over a couple of lines, where it's clear the variable is just for some plumbing and doesn't need a name
There are several things that involve unnamed, shortlived plumbing vars; as well as various languages pipeline notations, therr is also this in scala lambdas:
There are several things that involve unnamed, shortlived plumbing vars; as well as various languages pipeline notations, therr is also this in scala lambdas:
xs.map(x => x + 1)
can be written as: xs.map(_ + 1)
and even: (xs, ys).zipped.map((x,y)=>x+y)
as: (xs, ys).zipped.map(_ + _)Clojure's "threading" macros are exactly this: https://clojure.org/guides/threading_macros
Elixir's pipe is the same thing, though Clojure has a few extra forms to facilitate other variable passing patterns.
Elixir's pipe is the same thing, though Clojure has a few extra forms to facilitate other variable passing patterns.
We already have:
- partial application notation with numbered arguments
- pattern matching
- anaphoric if and related notations
- point-free form (no names at all)
- partial application notation with numbered arguments
- pattern matching
- anaphoric if and related notations
- point-free form (no names at all)
tidyverse packages in R do this. Normally, you might have something like this:
df = someFunctionThatReturnsADataFrame()
newDf = someFunctionThatTakesAndReturnsADataFrame(df)
doSomethingTo(df)
Since R lets you define your own operators, they took '%>%' and defined it as "pipe the return value from one function as the first argument to another function," so you can do this: someFunctionThatReturnsADataFrame() %>%
someFunctionThatTakesAndReturnsADataFrame() %>%
doSomethingTo()
No need to name either the temporaries or the function arguments.IRB the interactive ruby shell has _ which references the return value of the last command. So
10 + 10 puts _ # prints 20
but that isn't available in ruby itself
10 + 10 puts _ # prints 20
but that isn't available in ruby itself
I think a better format would be:
instead of:
instead of:
p(2 * 3 * 7) #=> 42
^^^^^var
Having: p(var1:[2*3] * var2: 7) => 42
p(var1) => 6
p(var2) => 7
The other requires ugly whitespacing.It kind of works in Python 3.9 and perhaps earlier, unfortunately need extra parentheses ...
>>> print((v1 := 2 * 3) * (v2 := 7))
42
>>> print(v1)
6
>>> print(v2)
7
edit: formattingHow do you reference a variable for plumbing if it doesn't have a name?
Would Elixir's pipe - https://elixir-lang.org/getting-started/enumerables-and-stre... - or Haskell's function composition - https://wiki.haskell.org/Function_composition - fit the criteria?
Those would. The Elixir style feels nice. I wonder if something like that could make it into Ruby 4
Mentioned in another sub-comment, but Clojure's threading macros do this. They do it by making positional assumptions about the implicit argument: https://clojure.org/guides/threading_macros
Wouldn't any concatenate language fit the bill?
https://concatenative.org/
Fantastic. Not on-board with the ^^^^ syntax - could be improved. But it reminds me of how sequential-character syntax is limiting, like if you were going to make an integrated circuit in strict 2 dimensions, without being able to bridge over traces sometimes in a minimally 3-dimensional way. This is like bringing programming into, literally, a new dimension.
Perhaps they could make use of all of those box-drawing characters that are just taking up space, and use them to pipe the characters in all sorts of directions!
https://en.wikipedia.org/wiki/Box-drawing_character
https://en.wikipedia.org/wiki/Box-drawing_character
Eh, like Funciton? https://esolangs.org/wiki/Funciton
I thought this might be some inverse of upvar from Tcl (which is not an April Fool):
https://www.tcl.tk/man/tcl/TclCmd/upvar.htm
https://www.tcl.tk/man/tcl/TclCmd/upvar.htm
The number of people that don't have their guard up on April 1 is always astounding.
I know this is a joke, but it really might be worth an experimental implementation, just to see where this leads. (Decent editor support would be critical.)
I can only imagine what the elegance and clarity when we start writing code in 3D.
Partisans in favor of spaces over tabs, here’s another argument for your arsenal.
Tabs are evil => https://www.emacswiki.org/emacs/TabsAreEvil
I see something different in there.
F(condition1,
Condition2)
Is worse than
F(
The problem isn't tabs or spaces, it's trying to align to the length of the function name instead of adding a new line
F(condition1,
Condition2)
Is worse than
F(
Condition1,
Condition2
)The problem isn't tabs or spaces, it's trying to align to the length of the function name instead of adding a new line
[deleted]
That kinda reminds me of Perl format [1]. It is not exactly whitespace dependent, though.
[1] https://perldoc.perl.org/perlform
[1] https://perldoc.perl.org/perlform
A truly inspired proposal!
[deleted]
Can't this just be solved by using a do/while loop?