[Cuis-dev] curried blocks

Boris Shingarov shingarov at labware.com
Thu Aug 15 11:49:23 PDT 2024


> I attached my solution as a fileOut. I'd love to get some feedback in
> terms of style and better ways to implement it.  What would you do
> differently?

I really really like what you did, for fundamental reasons.
Finally someone is looking at Smalltalk with an open mind!
I guess an enabling factor, which helps a lot, is not having
spent too many years in a particular Smalltalk-80 implementation.
As Andrés says in "DPBS Revisited":

> Reading DPBS with Smalltalk familiarity tends to reinforce
> a narrow point of view.

In this particular case — currying — if I am confined in a Smalltalk-80
implementation with broken #value: for 30 years, I lose the ability to
imagine anything else.

As a side note, even among Smalltalk-80 implementations not every one
lacks currying.  Smalltalk/X has had currying for decades (albeit it
doesn't invoke it by default).  And yeah, I would sure-as-hell love to
see it fixed in Cuis as well.

> Perhaps this has already been done and I just didn't find it.

Apart from the timid way how it's done in Smalltalk/X, Jan and I have been
using the fix in PreSmalltalks [1] for many years.  It enables some
seriously cool stuff; in fact we rely on it in all parts of our work
(MachineArithmetic, Tinyrossa etc.)  At the same time it doesn't break
anything in Pharo (i.e. nothing in Pharo demands bug-for-bug compatibility
with the old behavior — or at least we haven't come across anything that
does).  I guess I would compare the situation with how Squeak got closures
progressively fixed (although currying is much simpler).

Regarding your implementation, I do have criticisms of some details:

> cb := CurriedBlock block: [:a :b | a + b]

This is just straightforward wrong. There is no need to distinguish between
Block and CurryingBlock.  If

  [ :a :b | body ]

is not congruent to

  [ :a | [ :b | body ] ],

which is the same as saying that

  C raisedTo: A*B

is not congruent to

  (C raisedTo: B) raisedTo: A,

then it's an obvious bug, needing a (hopefully-)obvious fix.

> The goal is to be able to pass fewer arguments than a block requires

You meant "fewer or more arguments", right?  Because it's perfectly
valid to uncurry a nested block:

  [ :a | [ :b | a+b ] ] value: 2 value: 3   ">>> 5".


Now.
This is very nice but in Smalltalk we also have the "named" counterpart
to it, #perform:.  If we fix currying #value:, why not fix it in #perform:
too?  This allows stuff like [2]

  Integer>>factorial
    ^self unfold inject: 1 into: #*

and other "banana programming" [3,4]; in fact this is how the supercompiler
in MachineArithmetic [5] is able to reduce Gauss:

  0 + … + n

which is

  n unfold inject: 0 into: #+

to

  n * (n+1) / 2.

---

Are you on the BsAs Smalltalk slack?  There are some very interesting
discussions around these topics, especially in the #mathematics channel.

Best,
Boris

[1] https://github.com/shingarov/MachineArithmetic/blob/pure-z3/src/PreSmalltalks-Pharo/BlockClosure.extension.st#L98
[2] https://github.com/shingarov/MachineArithmetic/blob/pure-z3/src/MathNotation-Tests/Integer.extension.st#L7
[3] https://maartenfokkinga.github.io/utwente/mmf91m.pdf
[4] Gibbons, de Moor.  The fun of programming. (Palgrave, 2003)
[5] https://doi.org/10.1016/j.cola.2024.101275

On Fri, Aug 02, 2024 at 06:53:52PM -0500, Mark Volkmann via Cuis-dev wrote:
> I wanted to see if it was possible to define a class that supports partial
> application with blocks. The goal is to be able to pass fewer arguments
> than a block requires and get back a new "block" that requires
> the remaining arguments. Perhaps this has already been done and I just
> didn't find it.
> 
> Here are examples of using my solution:
> 
> cb := CurriedBlock block: [:a :b | a + b].
> cb valueWithArguments: #(2 3). "5"
> 
> cb2 := cb valueWithArguments: #(5). "a new CurriedBlock"
> cb2 valueWithArguments: #(7). "12"
> 
> I attached my solution as a fileOut. I'd love to get some feedback in terms
> of style and better ways to implement it. What would you do differently?
> 
> -- 
> R. Mark Volkmann
> Object Computing, Inc.


> -- 
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev



More information about the Cuis-dev mailing list