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

发布于 2024-08-07 01:57:08 字数 264 浏览 6 评论 0原文

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

例如,Python 似乎没有元类。 Smalltalk 没有生成器的概念。而且虽然都说是动态类型的,但我相信Python不做动态方法分派。这是正确的吗?

I've seen some comparisons between Smalltalk and Ruby on the one hand and Ruby and Python on the other, but not between Python and Smalltalk. I'd especially like to know what the fundamental differences in Implementation, Syntax, Extensiabillity and Philosophy are.

For example Python does not seem to have Metaclasses. Smalltalk has no concept of generators. And although both are said to be dynamicly typed, I believe that Python does not do dynamic method dispatch. Is this correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

勿忘心安 2024-08-14 01:57:08

比如Python好像没有
有元类。

它确实如此——它只是不会隐式地为每个类生成一个新的元类:它使用与父类相同的元类,或者默认情况下的 type 。 Python 的设计哲学,又名“Python 之禅”,可以通过在交互式解释器的提示下执行 import this 来深入了解;这里适用的一点是第二点,“显式优于隐式”。

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

class sic:
  __metaclass__ = mymeta
  ...

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

class sify(metaclass=mymeta):
  ...

Smalltalk 没有
生成器的概念。

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

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

由于 Smalltalk 具有一流的“代码块”(Ruby 从中获取了它们),因此您可以像其他“控制结构”一样,通过将代码块发送到一个合适的方法,如果您希望可以直接使用集合来做到这一点(想想 select:):

aCollection select: [:item | item doSomething].

因此在 Smalltalk(和 Ruby)中,您将代码块发送到迭代; Python 以相反的方式做事,迭代将值发送到周围的“调用”代码。看起来很不同,但最终并没有“深刻”的不同。

一流的代码块意味着 Smalltalk 不需要也不需要“控制结构”语句和关键字,例如 ifwhile:它们可以通过发送代码块来完成适当方法的参数(例如布尔值的ifTrue:方法)。 (Ruby 选择在第一类代码块中添加关键字/语句;我想说 Python [[显式]] 和 Smalltalk [[隐式]] 都像 C 一样尝试“提供一种执行操作的单一方法”,而 Ruby 则更多地属于 Perl 风格的“有很多方法可以做到这一点”)。

虽然
据说两者都是动态类型的,我
相信Python不会做
动态方法调度。这是
正确吗?

不,绝对不正确——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 中一样,通过附加括号显式执行调用,而“仅提及” ”,好吧...“只是提到”它,使其可用于任何类型的显式操作包括调用;-)。

For example Python does not seem to
have Metaclasses.

It sure does -- it just doesn't implicitly generate a new metaclass for every class: it uses the same metaclass as the parent class, or type by default. Python's design philosophy, aka "The Zen of Python", can be perused by doing import this at an interactive interpreter's prompt; the applicable point here is the second one, "Explicit is better than implicit."

In Python 2.X, you specify a custom metaclass with the following syntax:

class sic:
  __metaclass__ = mymeta
  ...

In Python 3.X, more elegantly, you use named-argument syntax:

class sify(metaclass=mymeta):
  ...

Smalltalk has no
concept of generators.

Python's generators are first-class (typically standalone) functions, and Smalltalk doesn't have the concept of "standalone" functions -- it has methods inside classes. But it certainly does have iterators -- as classes, of course:

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

Since Smalltalk has first-class "code blocks" (Ruby took them from it), you accomplish iteration, just like other "control structures", by sending a code block to a suitable method, and if you wish you can do that directly with the collection (think select:):

aCollection select: [:item | item doSomething].

So in Smalltalk (and Ruby) you send the code block to the iteration; Python does things the other way round, the iteration sends values out to the surrounding "calling" code. Looks very different, but not "deeply" different in the end.

First-class code blocks mean that Smalltalk doesn't need nor have "control structure" statements and keywords such as if or while: they can be accomplished by sending code blocks as arguments of appropriate methods (e.g. ifTrue: method of booleans). (Ruby chooses to have the keywords/statements in addition to the first-class code blocks; I would say that Python [[explicitly]] and Smalltalk [[implicitly]] both try, like C, to "offer a single way to perform an operation", while Ruby's more in the Perl-ish school of "there are many ways to do it").

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

No, absolutely incorrect -- Python intensely does dynamic method dispatch, to extremes. Consider for example:

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

By Python semantics, this performs 10 lookups for method bah in myobject -- just in case the previous execution of the method had caused myobject to entirely restructure itself internally so that its current bah method is completely different from the previous one (might be a pretty insane thing for the programmer to rely on such furious dynamism, but Python supports it). This is the reason that makes:

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

a common hand-optimization in Python code -- does one dynamic lookup before the loop instead of 10 inside the loop, one per leg (it's a case of "constant hoisting", since the compiler is forbidden from doing the "constant folding" itself by Python's extreme rules for dynamic lookups -- unless it can prove that it's guaranteed to be innocuous, and in practice such proof is too hard so Python implementations typically don't bother).

Python uses unified namespaces: methods are attributes of an object just like any other, except that they're callable. This is why extracting the method without calling it (known as a "bound method"), setting a reference to it in a variable (or stashing it into a list or other container, returning it from a function, whatever) is a plain and simple operation like in the above constant-hoisting example.

Smalltalk and Ruby have separate namespaces for methods and other attributes (in Smalltalk, non-methods attributes are not visible outside the object's own methods), so "extracting a method" and "calling the resulting object" require more introspective ceremony (but the common case of dispatching may be thereby made marginally simpler in certain cases -- in particular, "just mentioning" an argument-less method implicitly calls it, while in Python, like in C, calling is explicitly performed by appending parentheses, while "just mentioning", well... "just mentions" it, making it available for any sort of explicit operation including calling;-).

溺渁∝ 2024-08-14 01:57:08

Python 当然有元类。

Smalltalk 有一些不寻常的特性:

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

Python certainly does have metaclasses.

Smalltalk has some unusual features:

  • Has a rather simple syntax and only about 6 (!) keywords. Everything else (including defining new classes) is accomplished by calling methods (sending messages in Smalltalk). This allows you to create some DSL within the language.
  • In Smalltalk, you don't store source files, but instead have one big memory image and you modify it on the fly. You can also modify most of the Smalltalk itself (and possibly break it ;)
貪欢 2024-08-14 01:57:08

我一直在阅读工作中的编码员,这是一本非常好的书,里面充满了顶尖程序员的采访。不管怎样,其中一位是smalltalk的发明者,他详细地谈论了他的语言以及它与python的关系(他也非常喜欢python)。他对 python 的唯一问题是它的代码很慢...他真的很想将 Smalltalk jit 编译器作为 python 的后端,但不幸的是,由于该软件属于他工作的公司,这是不可能的。

无论如何……也许不是逐点比较,但这本书确实值得一读。

I've been reading coders at work which is a really nice book full of interviews with top programmers. Anyhow, one of them is the inventor of smalltalk and he talks in length on his language and how it relates to python (he likes python quite a bit as well). The only problem he had with python was it's slow code... he really wanted to have the smalltalk jit compiler as a backend for python, but unfortunately due to the software belonging to the company he worked for, this was not possible.

anyhow... maybe not a point by point comparison, but really a good read anyway this book.

我爱人 2024-08-14 01:57:08

Smalltalk 没有这个概念
发电机。

确实如此,但它们可以在大多数 Smalltalk 方言中从语言内部实现。 GNU Smalltalk 附带了生成器作为其流库的一部分。

Smalltalk has no concept of
generators.

True, but they can be implemented in most Smalltalk dialects from within the language. GNU Smalltalk comes with Generators as part of its stream library.

迷迭香的记忆 2024-08-14 01:57:08

根据 Wikipedia 关于动态方法分派的页面:

Smalltalk 实施

Smalltalk 使用基于类型的消息
调度员。每个实例都有一个
其定义包含的类型
方法。当一个实例收到一个
消息,调度员查找
中的相应方法
消息到方法的映射类型和
然后调用该方法。 [...]

许多其他动态类型
语言,包括 Python、Ruby、
Objective-C 和 Groovy 使用类似
方法。

添加了强调,并剪掉了一段。因此,两种语言至少在这部分看起来是相似的。

According to Wikipedia's page on dynamic method dispatch:

Smalltalk Implementation

Smalltalk uses a type based message
dispatcher. Each instance has a single
type whose definition contains the
methods. When an instance receives a
message, the dispatcher looks up the
corresponding method in the
message-to-method map for the type and
then invokes the method. [...]

Many other dynamically typed
languages, including Python, Ruby,
Objective-C and Groovy use similar
approaches.

Emphasis added, and one paragraph snipped. So, at least that part seems to be similar between the two languages.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文