У Smalltalk есть закрытия? - PullRequest
       43

У Smalltalk есть закрытия?

5 голосов
/ 12 июня 2011

Если у него есть замыкания, могу ли я предположить, что я могу использовать там много сильных техник функционального стиля?

Ответы [ 2 ]

7 голосов
/ 12 июня 2011

Да, у Smalltalk есть закрытия. Следующий код создает замыкание, которое возвращает сумму двух его аргументов:

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

Закрытия - это объекты, которые можно создавать, передавать и манипулировать ими. Для оценки закрытия вы отправляете value, value:, value:value:, ...

sum value: 1 value: 2.

Замыкания широко используются в коллекциях для итерации, фильтрации, сопоставления, ... всех значений коллекции:

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

Кроме того, они используются для управляющих структур, таких как петли:

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

Также условные выражения реализованы с использованием замыканий:

condition
   ifTrue: [ do this ]
   ifFalse: [ do that ]
5 голосов
/ 12 июня 2011

Pharo имеет их:

все виртуальные машины имеют поддержку закрытия, необходимую для последних изображений

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

Возвращает 5.

Но обратите внимание, что

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

не будет работать (Cannot store into ->init …), как (например) в 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

Если я не ошибаюсь,Это работало до появления нового компилятора замыкания.Я не уверен, почему он не работает с новым компилятором.

...