[GEP] Concatenative Method Calls

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[GEP] Concatenative Method Calls

Daniel.Sun
Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Daniel Sun
Apache Groovy committer

Blog: http://blog.sunlan.me
Twitter: @daniel_sun
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

Andrew Bayer
I actually find that less readable, and feel like it would get even worse with multiple parameters. I’m not sure I see what the value here would be.

A.

On Sun, Feb 25, 2018 at 8:39 AM Daniel.Sun <[hidden email]> wrote:
Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
MG
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

MG
Hi Daniel,

I agree with Andrew, the example to me looks less readable. Do you have another example that shows what application you had in mind ?

Cheers,
mg

-------- Ursprüngliche Nachricht --------
Von: Andrew Bayer <[hidden email]>
Datum: 25.02.18 15:02 (GMT+01:00)
Betreff: Re: [GEP] Concatenative Method Calls

I actually find that less readable, and feel like it would get even worse with multiple parameters. I’m not sure I see what the value here would be.

A.

On Sun, Feb 25, 2018 at 8:39 AM Daniel.Sun <[hidden email]> wrote:
Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
MG
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

MG
In reply to this post by Daniel.Sun
Intuitively the => arrow-operators point in the wrong direction, since I feel foo gets applied to x, etc...

How would additional arguments to an intermediate function be handled in this syntax ?

-------- Ursprüngliche Nachricht --------
Von: "Daniel.Sun" <[hidden email]>
Datum: 25.02.18 14:38 (GMT+01:00)
Betreff: [GEP] Concatenative Method Calls

Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
MG
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

MG
In reply to this post by Daniel.Sun
Intuitively the => arrow-operators point in the wrong direction, since I feel foo gets applied to x, etc...

How would additional arguments to an intermediate function be handled in this syntax ?

-------- Ursprüngliche Nachricht --------
Von: "Daniel.Sun" <[hidden email]>
Datum: 25.02.18 14:38 (GMT+01:00)
Betreff: [GEP] Concatenative Method Calls

Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

David Dawson
In reply to this post by Daniel.Sun
Hello. 

I conceptually like this a lot, its a very dataflow style approach to the problem

Conceptually, its similar to

[1,2,3].map { it * 2 }.each { println it }

Or in a unix shell

cat file | grep x | echo

Or perhaps something more reactive streams ish.

In any case, its re-arranging the function call order to visually be in the order that it actually happens, rather than inside out, as is "normal"

You could imagine the above chained method calls (which is given to us by extension methods on groovy collections) as something more generic using this form.  Imagine that we have a new collection type, not implementing the java collections api (like one of the dodgy SAX libraries or something). You can't do the method chaining transformation above.  What you want to do is to arrange a pipeline of function calls.

Instead of having to do something contrived like

printIt(timesTwo([1,2,3]))

You could do something more like

[1,2,3] => timesTwo => printIt

So, with "generic" methods, unattached to any types via extension methods, you gain much of the same benefit as method chained transforms on Collections, but everywhere.

So, I'm certainly a fan of something like this, even if the fat arrow syntax might not be the best/ one I'd choose necessarily. 

Personally, I'd like a " | ", if it can be made to fit in somehow, as thats a very familiar syntax for the concept from the shell world

David.






On 25 February 2018 at 14:17, mg <[hidden email]> wrote:
Intuitively the => arrow-operators point in the wrong direction, since I feel foo gets applied to x, etc...

How would additional arguments to an intermediate function be handled in this syntax ?

-------- Ursprüngliche Nachricht --------
Von: "Daniel.Sun" <[hidden email]>
Datum: 25.02.18 14:38 (GMT+01:00)
Betreff: [GEP] Concatenative Method Calls

Hi all,

     I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

      Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

Jesper Steen Møller
In reply to this post by Daniel.Sun
Interesting proposal and discussion!

As somebody who routinely work in both Java, Groovy, TypeScript/ES6 and C#, I find this syntactically too close too arrow functions/lambdas, in other words, they may confuse a lot of readers.

As for the semantic content: I realize that Groovy goes a long way to support multiple paradigms, but I feel this is trying to cater to the needs of concatenative / point-free style programming, in a language and environment which doesn't really have the functional compositionality to take advantage of it -- because Groovy is at its heart object-oriented.

Your proposal is essentially the forward pipe operator |> for function composition, as seen in a number of functional languages, like F# and Elm (as "&" in Haskell). In those languages, it makes a lot of sense, since the function is the primarily compositional building block. In Groovy, it's the object, and many of the core features of Groovy (like overloading, extension methods, AST transformations, closures) are added to support those. In practice, I've seen very little Groovy code which ends up being formulated as baz(bar(foo(x))) -- but I've seen a lot of  x.foo().bar().baz() instead. It's a better match, and Groovy already has a great operator "." to make programs easy to read and type

-Jesper

On 25 Feb 2018, at 14.38, Daniel.Sun <[hidden email]> wrote:

Hi all,

    I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

     Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

Guillaume Laforge
Administrator
Quick note in the discussion: we have already a form of composition with closures, using the right shift operator:


Le dim. 25 févr. 2018 à 16:02, Jesper Steen Møller <[hidden email]> a écrit :
Interesting proposal and discussion!

As somebody who routinely work in both Java, Groovy, TypeScript/ES6 and C#, I find this syntactically too close too arrow functions/lambdas, in other words, they may confuse a lot of readers.

As for the semantic content: I realize that Groovy goes a long way to support multiple paradigms, but I feel this is trying to cater to the needs of concatenative / point-free style programming, in a language and environment which doesn't really have the functional compositionality to take advantage of it -- because Groovy is at its heart object-oriented.

Your proposal is essentially the forward pipe operator |> for function composition, as seen in a number of functional languages, like F# and Elm (as "&" in Haskell). In those languages, it makes a lot of sense, since the function is the primarily compositional building block. In Groovy, it's the object, and many of the core features of Groovy (like overloading, extension methods, AST transformations, closures) are added to support those. In practice, I've seen very little Groovy code which ends up being formulated as baz(bar(foo(x))) -- but I've seen a lot of  x.foo().bar().baz() instead. It's a better match, and Groovy already has a great operator "." to make programs easy to read and type

-Jesper

On 25 Feb 2018, at 14.38, Daniel.Sun <[hidden email]> wrote:

Hi all,

    I propose to introduce Concatenative Method Calls to Groovy. It can
make code more readable, for example:

Currently we write method calls like:
y = foo(x)
z = bar(y)
w = baz(z)
OR
w = baz(bar(foo(x)))

Concatenative Method Calls(inspired by [1]):
w = x => foo => bar => baz

     Any thoughts?

Cheers,
Daniel.Sun
[1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

Daniel.Sun
Hi Guillaume,

     I have to admit closure is very versatile...

     In practice, chained closures are a bit verbose :-(

(obj1.&m1 >> obj2.&m2 >> obj3.&m3)(someParam)

     In addition, chained closures seems not to support multiple parameters.
While I propose the following syntax to support multiple parameters.

(x, y) => m1 => (m2, param) => m3

P.S.  I like Jesper proposed |> to replace =>

Cheers,
Daniel.Sun





--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Daniel Sun
Apache Groovy committer

Blog: http://blog.sunlan.me
Twitter: @daniel_sun
Reply | Threaded
Open this post in threaded view
|

Re: [GEP] Concatenative Method Calls

Jochen Theodorou
In reply to this post by Daniel.Sun
On 25.02.2018 14:38, Daniel.Sun wrote:

> Hi all,
>
>       I propose to introduce Concatenative Method Calls to Groovy. It can
> make code more readable, for example:
>
> Currently we write method calls like:
> y = foo(x)
> z = bar(y)
> w = baz(z)
> OR
> w = baz(bar(foo(x)))
>
> Concatenative Method Calls(inspired by [1]):
> w = x => foo => bar => baz
>
>        Any thoughts?
>
> Cheers,
> Daniel.Sun
> [1] https://en.m.wikipedia.org/wiki/Concatenative_programming_language

I think if we want to become a concatenative programming language, we
should first try to allow tacit programming... I would not start with
composition here. You start with how to actually reference a function in
the first place. If you go with method references you can do some things:

this.&baz << this.&bar << this.&foo (x)

Or with a lambda style:

this::baz << this::bar << this::foo (x)

And you can even leave the (x) to get the composition. And you can do
even something like

def barfoo = this::bar << this::foo
this::baz << barfoo (x)

In your variant I find it questionable if you can do without the "this".
Otherwise you will have an overlap between local variables and methods.

So what I would like to see is 1-n more complex examples, that do not
concentrate on one line only. It should contain a "reference" to method,
that is no on "this"; it should show how the shadowing by a local
variable is supposed to be handled (if any); and it show how arguments
are handled, especially for different arities... After that we can talk
about if that is really better readable.

I actually do think our method references need rework in how they are
formed, because they are actually functionally incomplete, as can be
easily seen in this example:

> class X {
>   private bar(){1}
>   def b = this.&bar
> }
> println new X().b()
> class Y extends X {}
> println new Y().b()

That's why I said I would prefer cleaning those elements up and make
them actually working correctly before we go to composition in the next
step and then talk maybe about a concatenative programming language and
how much that clashes with command expressions ;)

bye Jochen

12