Как Smalltalk (например, Pharo) сравнивается с Python? - PullRequest
6 голосов
/ 02 октября 2009

Я видел некоторые сравнения между Smalltalk и Ruby с одной стороны и Ruby и Python с другой, но не между Python и Smalltalk . Мне особенно хотелось бы знать, каковы фундаментальные различия в реализации, синтаксисе, расширяемости и философии.

Например, у Python нет метаклассов. Smalltalk не имеет понятия о генераторах. И хотя оба говорят, что они динамически типизированы, я считаю, что Python не выполняет динамическую диспетчеризацию методов. Это правильно?

Ответы [ 5 ]

9 голосов
/ 02 октября 2009

Например, Python, похоже, не есть метаклассы.

Конечно, это так - просто неявно генерирует новый метакласс для каждого класса: он использует тот же метакласс, что и родительский класс, или type по умолчанию. Философия дизайна 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 не нуждается и не имеет операторов «контрольной структуры» и таких ключевых слов, как if или while: они могут быть выполнены путем отправки кодовых блоков в качестве аргументов соответствующих методов (например, ifTrue: метод логических значений). (Ruby выбирает ключевые слова / операторы в дополнение к блокам кода первого класса; я бы сказал, что Python [[явно]] и Smalltalk [[неявно]] оба пытаются, как C, выполнить " предложить один способ выполнения операции ", в то время как Руби больше в школе Perl-ish" есть много способов сделать это ").

И хотя оба, как говорят, динамически набираются, я считаю, что Python не делает динамический метод отправки. Это исправить?

Нет, абсолютно неверно - Python интенсивно выполняет динамический метод отправки, в крайности . Рассмотрим для примера:

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

По семантике Python это выполняет 10 поисков для метода bah в myobject - на тот случай, если предыдущее выполнение метода вызвало myobject полную внутреннюю реструктуризацию, так что его текущий bah метод полностью отличается от предыдущего (для программиста может показаться довольно безумной вещью полагаться на такой яростный динамизм, но Python его поддерживает). Это причина, которая делает:

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

распространенная ручная оптимизация в коде Python - выполняет один динамический поиск перед циклом вместо 10 внутри цикла, по одному на ногу (это случай «постоянного подъема», поскольку компилятору запрещено делать «постоянный» сворачивание "себя" по экстремальным правилам Python для динамического поиска - если только он не может доказать, что он гарантированно безопасен, и на практике такое доказательство является слишком сложным, поэтому реализации Python обычно не беспокоятся).

Python использует унифицированные пространства имен: методы являются атрибутами объекта, как и любой другой, за исключением того, что они могут быть вызваны. Вот почему извлечение метода без его вызова (известного как «связанный метод»), установка ссылки на него в переменной (или сохранение его в списке или другом контейнере, возвращение его из функции, что угодно) является простым простая операция, как в приведенном выше примере с постоянным подъёмом.

Smalltalk и Ruby имеют отдельные пространства имен для методов и других атрибутов (в Smalltalk атрибуты, не относящиеся к методам, не видны за пределами собственных методов объекта), поэтому для «извлечения метода» и «вызова результирующего объекта» требуется более интроспективная церемония ( но общий случай диспетчеризации, таким образом, может быть несколько упрощен в некоторых случаях - в частности, «просто упоминание» метода без аргументов неявно вызывает его, в то время как в Python, как и в C, вызов явно выполняется добавлением скобок, в то время как «просто упоминая», ну ... «просто упоминает» об этом, делая его доступным для любых явных операций , включая вызов; -).

7 голосов
/ 02 октября 2009

Python определенно имеет метаклассы.

Smalltalk имеет некоторые необычные особенности:

  • Имеет довольно простой синтаксис и всего около 6 (!) Ключевых слов. Все остальное (включая определение новых классов) выполняется путем вызова методов (отправка сообщений в Smalltalk). Это позволяет вам создавать некоторые DSL на языке.
  • В Smalltalk вы не храните исходные файлы, а вместо этого имеете один большой образ памяти и изменяете его на лету. Вы также можете изменить большую часть самого Smalltalk (и, возможно, нарушить его;)
2 голосов
/ 10 декабря 2009

Smalltalk не имеет понятия генераторы.

Да, но они могут быть реализованы на большинстве диалектов Smalltalk изнутри языка. GNU Smalltalk поставляется с Generators в составе потоковой библиотеки .

2 голосов
/ 02 октября 2009

Я читал кодеров на работе , это действительно хорошая книга, полная интервью с лучшими программистами. Во всяком случае, один из них является изобретателем smalltalk, и он подробно рассказывает о своем языке и о том, как он относится к python (ему также очень нравится python). Единственная проблема, с которой он столкнулся с python - это медленный код ... он действительно хотел, чтобы jit-компилятор smalltalk использовался в качестве бэкэнда для python, но, к сожалению, из-за программного обеспечения, принадлежащего компании, в которой он работал, это было невозможно.

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

1 голос
/ 02 октября 2009

Согласно странице Википедии о динамическом методе отправки:

Реализация Smalltalk

Smalltalk использует сообщение на основе типа диспетчер. Каждый экземпляр имеет один тип, определение которого содержит методы. Когда экземпляр получает сообщение, диспетчер ищет соответствующий метод в карта сообщение-метод для типа и затем вызывает метод. [...]

Многие другие динамически набираемые языки, включая Python , Ruby, Objective-C и Groovy используют аналогичные подходы.

Акцент добавлен, и один абзац обрезан. Так что, по крайней мере, эта часть кажется похожей между двумя языками.

...