Smalltalk可变函数

Smalltalk可变函数,smalltalk,if-statement,variadic-functions,pharo,control-structure,Smalltalk,If Statement,Variadic Functions,Pharo,Control Structure,Smalltalk(特别是Squeak/Pharo)是否具有某种形式的可变函数 我刚刚在smalltalk中读到关于设计自己的控制语句的能力,而我是ifTrue的忠实粉丝:IfAlse:我很难想出一个好方法来实现任意if,if else,if else,…,else语句,我在想这些变量函数对于实现case语句是多么有用。差不多 假类 ifTrue: aBlock (... elseIf: aBoolean then: aSecondBlock ...) else: aLastBlock vAr

Smalltalk(特别是Squeak/Pharo)是否具有某种形式的可变函数

我刚刚在smalltalk中读到关于设计自己的控制语句的能力,而我是ifTrue的忠实粉丝:IfAlse:我很难想出一个好方法来实现任意if,if else,if else,…,else语句,我在想这些变量函数对于实现case语句是多么有用。差不多

假类

ifTrue: aBlock (... elseIf: aBoolean then: aSecondBlock ...) else: aLastBlock

vArgList pairsDo: [:x :y| x ifTrue:[^ (y value)] ].
^ aLastBlock

Smalltalk方法调用的类关键字语法本质上定义了方法的算术性。没有像Common Lisp中那样的
&rest
模式

当然,您可以让一个方法获取一个列表,比如
BlockClosure>>valueWithArguments:
,但这几乎不是一回事

您可以修改
编译器
,以支持可变方法调用。可能调用只是在每个变量之间使用
和:

(条件)如果真的:a锁定elseIf:a带:a第二个块带:另一个布尔带:a第三个块

您可以使用
#caseOf:否则:
消息。 查找此邮件的某个发件人以获取示例


但是无论如何,如果你想使用用例语句,你就没有遵循smalltalk的做事方式。告诉我们您希望通过案例陈述实现什么,以便我们可以向您展示一些更干净的方法

我在编程中学到的一件事不是你不需要case语句,而是你不想要case语句

Case语句是膨胀对象的方式。当您使用它时,您正在降低维护的质量。那时你会有你想要的所有可能性,但是当你想添加一些东西的那一天,当你不再记得该对象的职责的微妙之处时,你就必须检查讨厌的代码,所以你会更加膨胀它

在短期内,他们看起来很友好,但案例陈述不是你的朋友。从长远来看,它们会咬你

此外,它们还降低了代码的灵活性。例如,您不能自信地添加关于前面代码的案例。当你不记得为什么要这样编码的时候,你不得不回顾旧代码

Case语句是好代码的敌人

如果你有超越ifTrue:ifFalse:的东西,那么正确的做法是对此进行说明。所以你要做的是实现三个非常简单的类,它们都理解一些动词

说,“做下一件事。”。因此,当对象接收到消息时,它会将其委托给状态(以3个(或30个,请注意,这可以很好地扩展复杂性)中的一个为准),并且状态知道如何使原始接收者做出正确的反应

这将使您的代码轻巧、明显且高度可维护。您将能够忘记这一点,因为您知道,当您再次查看它时,一切都非常明显,您不需要像思考代码的未来一样思考代码的过去

这很重要,因为你的内存是你拥有的最昂贵的内存,而AFAIK是不可升级的。所以这项技术可以让你做更强大的事情


此外,对一些人来说,上3节课可能听起来像是更多的工作,但事实并非如此。任何noob都可以在一瞬间添加3个空类,但只有合适的专家才能记住旧代码中case语句是如何按照其生成方式生成的。如果你非常乐观,那么回忆起来需要几分钟,这样你们都知道下一步该做什么。想想看。

你不能只修改编译器。您还需要修改VM。因为参数的数量在BlockClosure中,它告诉要创建的上下文的大小(包括参数的数量)。对于我来说,很难看到如何从可读性方面改进Andreas Raab在DnsClient(关于SqueakSource)中使用的#caseOf:others:in。