Just for one mor eexample - I have a toy implementation here as well:
https://github.com/jsbueno/chillicurry 
I decided to use the "." operator itself, and frame introspection to retrieve the function
to be called from the calling context - that is rude, I know.

But what I like of this approach is that by using the "." I have full control of the objects called as functions
on the chain - which allowed me to use a constant value that will be replaced by the "dynamic" parameter from 
previous function calls.

So, if I want "max(len(mytext), 10)", I can write "curry.max(DELAY, 10).len(mytext)"   - the "max" call will only take place after len is evaluated. (And for functions wth a single parameter, there is no need for that)

Lessons learned: 
1) One wanting curry can do so without changing Python Syntax
2) For control of functions that need more than one parameter, one needs a lazy-call mechanism.

Possibly the "lazy call" mechanism would be a more interesting "add on" to the language than currying per se. (It is
due to not being able to lazy call that I resort to the transforms using ".")

That said, if anyone like the the "chillicurry" approach enough that wants to help polishing it enough for pypi,
 just get in touch.

   js
  -><-


On 29 January 2017 at 18:38, David Mertz <mertz@gnosis.cx> wrote:
The `tools` (and `cytoolz` that has an identical API) provides an `@curry` decorator that is more general and elegant than the links earlier IMO.  Maybe I'm biased because I work with principal author Matt Rocklin, but toolz is really neat.

See: http://toolz.readthedocs.io/en/latest/curry.html



On Sun, Jan 29, 2017 at 3:08 AM, zmo via Python-ideas <python-ideas@python.org> wrote:
tl;dr: I agree with you, Steven, as proven by my former post, augmented
with the details of your reply: there's no advantage to add a new
operator and language construct for this use case.—

On Sun, Jan 29, 2017 at 01:30:13PM +1100, Steven D'Aprano wrote:
> On Sat, Jan 28, 2017 at 03:16:27PM +0100, zmo via Python-ideas wrote:
> > This idea sounds fun, so as a thought experiment why not imagine one
> > way of integrating it in what I believe would be pythonic enough.

> This idea is sometimes called "the Collection Pipeline" design pattern,
> and is used in various command shells. Martin Fowler wrote about this
> design pattern here:
> https://martinfowler.com/articles/collection-pipeline/
> and I wrote a recipe for it:
> https://code.activestate.com/recipes/580625-collection-pipeline-in-python/
> with a working, although basic, implementation.
>     print(list(map(float, filter(lambda n: 20 < n < 30, data))))
> […]
>     data | Filter(lambda n: 20 < n < 30) | Map(float) | List | Print

It's indeed an interesting tip and idea, and using the pipe is not a bad
idea as it's a good mnemonic for anyone who used a shell. About reading
order, I'm personally agnostic.

> (In principle, Python built-ins could support this sort of syntax so I
> could write filter, map, list, print rather than custom versions Filter,
> Map, etc. […] But for Python that would be a *major* change, and not one I
> wish to propose. […])

Even as an external library, I would use that kind of syntax with
extreme care in python. As a python developer, one of the things I
really do enjoy is that any python code looks like a python code, and
that's because changing meaning of operators depending on the context is
discouraged.

Then, unlike Scala, C++ or Ruby, you never end up with the language
looking like a new DSL for each application or framework.

> > On Sat, Jan 28, 2017 at 12:41:24PM +0000, Ed Kellett wrote:
> > So, considering it's decided that the RHS is in charge of filling up all
> > the arguments of the LHS,
> Is that actually decided?

it's not, it's part of the thought experiment of 'if we had such syntax',
how could we handle arguments?

> […] so either we have a new, parallel series of functions including
> Filter(...) or we write something like:
>     print XYZ list XYZ map XYZ lambda (f1, f2, arg): (f1, filter(f2, arg))(float, lambda n: 20 < n < 30, data)
> which is simply horrid. Maybe there could be a series of helper
> functions, but I don't think this idea is workable. […]

> > […]
> > All in all, it can be a nice syntactic sugar to have which could make it
> > more flexible working with higher order functions, but it with the way
> > I'm suggesting to comply with python's arguments handling, it offers
> > little advantages when the RHS is not filling LHS arguments:
> > […]
> I think that "literal advantage" is being very kind. The best you can
> say is that you save two pairs of parentheses at the cost of three
> operators and moving arguments away from the functions that use them.

I said "little" not "literal" ☺ I started the whole reasoning trying to
be objective and figure how such a new syntax would be integrated in
python and what good use could be made of it. And in the end, I end up
with something that can offer a nice syntax for a very niche case, and
wouldn't be of much use most of the time.

The fact that it can be implemented with some operator overload, as you
nicely demonstrated just proves the fact further: this is not a good
idea.

> [...]
> > But then it would be just another way to introduce currying as a
> > language feature with an operator, so we should then just discuss on how
> > to add currying as a language syntax "by the book", but I'm pretty sure
> > that's a topic already discussed before I joined this list ;-)
> The easiest way to support currying, or at least some form of it, is:
>     from functools import partial as p
>     p(map, float)  # curries map with a single argument float
> which is not quite the map(float) syntax Haskell programmers expect,
> but its not awful.

Indeed, I love having that available as a function! We could reopen the
debate as to whether we should implement currying into python, but since
my last post I've done a bit of searching, and found out it's been
discussed 14 years ago:

https://mail.python.org/pipermail/python-dev/2004-February/042668.html
https://www.python.org/dev/peps/pep-0309/

and a few discussions, implementations of (real) currying published more
recently:

https://mtomassoli.wordpress.com/2012/03/18/currying-in-python/
http://code.activestate.com/recipes/577928-indefinite-currying-decorator-with-greedy-call-and/
https://gist.github.com/JulienPalard/021f1c7332507d6a494b

I could argue that a nicer syntactic sugar and having it as a language
feature could help in having it supported in a more optimised fashion,
instead of using an added layer of abstraction. But, I won't ^^

Cheers,

--
zmo
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/



--
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/