Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Smalltalk have closures?

If it has closures, can I assume that I can use many of strong functional style techniques on there?

like image 559
eonil Avatar asked Jun 12 '11 15:06

eonil


2 Answers

Yes, Smalltalk has closures. The following code creates a closure that returns the sum of its two arguments:

sum := [ :a :b | a + b ].

Closures are objects that can be instantiated, passed around and manipulated. To evaluate a closure you send value, value:, value:value:, ...

sum value: 1 value: 2.

Closures are prominently used with collections to iterate, filter, map, ... all values of a collection:

aCollection select: [ :each | each isOdd ].
aCollection inject: 0 into: [ :each :result | each + result ].

Furthermore, they are used for control structures like loops:

[ iterator hasNext ]
    whileTrue: [ iterator next ].
1 to: 10 do: [ :each | ... ].

Also conditionals are implemented using closures:

condition
   ifTrue: [ do this ]
   ifFalse: [ do that ]
like image 70
Lukas Renggli Avatar answered Sep 30 '22 19:09

Lukas Renggli


Pharo has them:

all VMs have closure support required for latest images

makeAdder := [ :x | [ :y | x + y ]].
add2 := makeAdder value: 2.
add2 value: 3.

Returns 5.

But notice that

makeCounter := [ :init | [ init := init + 1. init ]].

won't work (Cannot store into ->init …), like (for example) in CL:

CL-USER> ((lambda (init) (lambda () (incf init))) 0)
#<COMPILED-LEXICAL-CLOSURE #xC7A495E>
CL-USER> (funcall *)
1
CL-USER> (funcall **)
2
CL-USER> (funcall ***)
3

If I'm not mistaken, this used to work before the new closure compiler was introduced. I'm not sure why it doesn't work with the new compiler.

like image 41
danlei Avatar answered Sep 30 '22 21:09

danlei