Smalltalk(例如Pharo)与Python相比如何?

2024-06-01 08:02:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我看到过Smalltalk和Ruby之间的一些比较,Ruby和Python,但是Python和Smalltalk之间没有。我特别想知道在实现、语法、可扩展性和哲学方面的根本区别是什么。在

例如Python似乎没有元类。Smalltalk没有发电机的概念。尽管这两种方法都被称为动态类型,但我相信Python并不执行动态方法分派。这是对的吗?


Tags: 方法概念分派类型语法动态发电机可扩展性
3条回答

Python确实有元类。在

Smalltalk有一些不同寻常的特点:

  • 有一个相当简单的语法,只有大约6(!)关键词。其他一切(包括定义新类)都是通过调用方法(用Smalltalk发送消息)来完成的。这允许您在语言中创建一些DSL。在
  • 在Smalltalk中,您不存储源文件,而是有一个大内存映像,您可以动态地修改它。您还可以修改Smalltalk本身的大部分内容(并可能破坏它;)

For example Python does not seem to have Metaclasses.

它确实是这样——它只是不隐式地为每个类生成一个新的元类:它使用与父类相同的元类,或者默认使用type。Python的设计理念,也就是“Python的禅”,可以通过在交互式解释器的提示下执行import this来阅读;这里的适用点是第二点,“显式优于隐式”

在Python 2.X中,使用以下语法指定自定义元类:

class sic:
  __metaclass__ = mymeta
  ...

在Python 3.X中,更优雅的是,使用命名参数语法:

^{pr2}$

Smalltalk has no concept of generators.

Python的生成器是一级(通常是独立的)函数,Smalltalk没有“独立”函数的概念——它在类中有方法。但它确实有迭代器——当然,作为类:

iterator := aCollection iterator.
[iterator hasNext] whileTrue: [iterator next doSomething]. 

由于Smalltalk有一流的“代码块”(Ruby从中提取了代码块),所以您可以像其他“控制结构”一样,通过将代码块发送到合适的方法来完成迭代,如果您希望可以直接使用集合来完成这一步(想想select:):

aCollection select: [:item | item doSomething].

因此,在Smalltalk(和Ruby)中,将代码块发送给迭代;Python则相反,迭代将值发送给周围的“调用”代码。看起来很不一样,但最终没有“深刻”的不同。在

第一类代码块意味着Smalltalk不需要也不需要诸如ifwhile之类的“控制结构”语句和关键字:它们可以通过发送代码块作为适当方法的参数来实现(例如booleans的ifTrue:方法)。(Ruby选择在一级代码块中添加关键字/语句;我想说Python[[显式]]和Smalltalk[[隐式]]都试图像C一样“提供一种执行操作的方法”,而Ruby更像Perl学派中的“有许多方法可以做到这一点”)。在

And although both are said to be dynamicly typed, I believe that Python does not do dynamic method dispatch. Is this correct?

不,绝对不正确——Python强烈地执行动态方法调度,到了极点。例如:

for i in range(10):
  myobject.bah()

根据Python语义,这将对myobject中的方法bah执行10次查找,以防该方法先前的执行导致myobject在内部完全重构自身,因此其当前的当前bah方法与之前的方法完全不同(对于程序员来说,这可能是一件相当疯狂的事情)但Python支持它)。这就是为什么:

themethod = myobject.bah
for i in range(10):
  themethod()

Python代码中一个常见的手工优化——在循环之前而不是在循环内执行10次动态查找,每一段执行一次(这是“持续提升”的一种情况,因为Python的动态查找的极端规则禁止编译器自己进行“常量折叠”,除非它能证明它是无害的,而且在实践中,这样的证明太难了,所以Python实现通常不必费心)。在

Python使用统一的名称空间:方法和其他方法一样是对象的属性,只是它们是可调用的。这就是为什么提取方法而不调用它(称为“绑定方法”),在变量中设置对它的引用(或将它存储到列表或其他容器中,从函数返回它,无论是什么)都是一个简单而简单的操作,就像上面的常量提升示例一样。在

Smalltalk和Ruby对方法和其他属性有单独的名称空间(在Smalltalk中,非方法属性在对象自己的方法之外是不可见的),因此,“提取一个方法”和“调用结果对象”需要更多的自省(但是在某些情况下,调度的常见情况可能会稍微简单一些——特别是“只提到”一个无参数的方法隐式调用它,而在Python中,就像在C中,调用是通过附加括号显式地执行的,而“只是提到”,嗯只是男人它可以用于任何类型的显式操作,包括调用;-)。在

我一直在读coders at work这是一本非常不错的书,里面有很多高级程序员的访谈。总之,其中一个是smalltalk的发明者,他详细地讲述了他的语言以及它与python的关系(他也非常喜欢python)。他对python的唯一问题是它的代码太慢。。。他真的很想用smalltalk jit编译器作为python的后端,但不幸的是,由于软件属于他工作的公司,这是不可能的。在

无论如何。。。也许不是一点一点的比较,但无论如何这本书确实是一本很好的读物。在

相关问题 更多 >