More Questions on the Path to Combinatory Python


I was just thinking yesterday that I need to get back to the posts I was intending to make after my initial post of the month, Two Fun(ctional) Questions. Then tonight Eric Florenzano made an excellent post on Lambda Calculus which is related to my topic of interest.

So let me take one of his examples and raise again the issue from my first post.

First of all, consider the following Python function taking two arguments:

>>> add_ = lambda x, y: x + y

This function works as expected:

>>> add_(5, 4) 9

Eric shows a curried version defined in Python:

>>> add = lambda x: lambda y: x + y

and shows how, when given one number, this returns a function that takes a second number and adds it to the first:

>>> add(5)(4) 9

To emphasize my desire to blur the distinction between functions and constants, I'd like to point out the following works too:

>>> (add)(5)(4) 9

But imagine we want to add three numbers. With our two-argument version, we could say:

>>> add_(5, add_(2, 2)) 9

How would we do that with our curried version? I'm NOT talking about defining a new 'add', I'm talking about using multiple applications of the original 'add' just like we did with 'add_' above.

The following works:

>>> (add)(5)((add)(2)(2)) 9

but note the additional parentheses we had to add. If we wanted to instead defer the application of the final argument we'd have to rewrite it as:

>>> (add)((add)(5)(2)) <function <lambda> at 0x755f0> >>> (add)((add)(5)(2))(2) 9

So the question is: is there a way to modify add (hopefully with just a wrapper that could be applied to any unary function) such that the following work:

(add)(5)(add)(2) (add)(5)(add)(2)(2)

where the former is equivalent to (add)(7) and the latter returns 9?

And is this pretty much the same question I asked in my original post with the very same solution(s)?

By the way, here is another example that should work in any true solution...

If I define

>>> M = lambda x: (x)(x)

then we should be able to get

(add)(M)(1)

to return 2.

Or is this whole hybrid approach destined to failure and the only real way to use combinators is with Church-encoded numerals?

The original post was in the categories: python algorithms combinatory_python but I'm still in the process of migrating categories over.

The original post had 11 comments I'm in the process of migrating over.