Smalltalk 中的函数对象(或执行没有“value:”的块)
是否可以向对象发送匿名消息?我想组合三个像这样的对象(想想 FP):
" find inner product "
reduce + (applyToAll * (transpose #(1 2 3) #(4 5 6)))
其中 reduce
、applyToAll
和 transpose
是对象,而 +
>、*
和两个数组是传递给发送给这些对象的匿名消息的参数。是否可以使用块来实现相同的效果? (但没有显式使用 value:
)。
Is it possible to send an anonymous message to an object? I want to compose three objects like this (think FP):
" find inner product "
reduce + (applyToAll * (transpose #(1 2 3) #(4 5 6)))
where reduce
, applyToAll
and transpose
are objects and +
, *
and the two arrays are arguments passed to anonymous messages sent to those objects. Is it possible to achieve the same using blocks? (but no explicit usage of value:
).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许您真正想做的是在 Smalltalk 中定义 DSL?
Perhaps what you really want to do is define a DSL inside Smalltalk?
当 aRealObject 定义了正确的方法时就会起作用。哪里需要块?
would work when aRealObject has defined the right methods. Where do you need a block?
您正在寻找
doesNotUnderstand:
。如果reduce
是一个未实现+
的对象,但您还是发送了它,则将调用其doesNotUnderstand:
方法。通常它只会引发错误。但是您可以覆盖默认值,并访问选择器+
和其他参数,并对它们执行任何您喜欢的操作。为了简单起见,创建一个类
Reduce
。在其类方面,定义方法:然后您可以像这样使用它:
在 Squeak 工作区中,如预期的那样,答案为 32。
它之所以有效,是因为
*
已经为具有合适语义的集合实现了。或者,使用此类端方法添加一个类
ApplyToAll
:并将此方法添加到
SequenceableCollection
:然后您可以编写
与您最初的想法非常接近的代码。
You are looking for
doesNotUnderstand:
. Ifreduce
is an object that does not implement+
but you send it anyway, then instead itsdoesNotUnderstand:
method will be invoked. Normally it just raises an error. But you can override the default, and access the selector+
and the other argument and do whatever you like with them.For simplicity, create a class
Reduce
. On its class side, define the method:Then you can use it like this:
which in a Squeak workspace answers 32, as expected.
It works because
*
is already implemented for Collections with suitable semantics.Alternatively, add a class
ApplyToAll
with this class-side method:and also add this method to
SequenceableCollection
:Then you can write
which is pretty close to your original idea.