juan_gandhi: (Default)
Juan-Carlos Gandhi ([personal profile] juan_gandhi) wrote2008-05-14 12:56 pm

dynamic vs static

Я не собираюсь вступать в эту нонешнюю дискуссию. Просто хочу заметить, что речь идёт о "гарвардской архитектуре" супротив "архитектуры фон Неймана".

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

Во второй что данные, что код, без разницы; код - это вид данных, а данные могут на определённом уровне интерпретироваться как код, или строить код, который эти данные сынтепретирует (как, помню, была какая-то база, которая строила классы для доступа прямо при открытии таблицы: взял таблицу - вот и классы загрузились; естественно, что динамически.

Ну а так, наверное, стоит почитать, конечно: Егге устраивает разгром в столице статической типизации
nine_k: A stream of colors expanding from brain (Default)

[personal profile] nine_k 2008-05-18 09:28 pm (UTC)(link)
С удовольствием подсуну. Но дело, как вы правильно замечаете, хитрее, чем кажется.
$ cat fj.py
def a():
   print "fj's a"

def b():
   a()
   foo()
Добавим для наглядности вызов некоторой неизвестно где определённой функции foo, которую надо искать "снаружи".
$ python
Python 2.4.5 (#2, Apr 17 2008, 13:00:52) 
[GCC 4.2.3 (Debian 4.2.3-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from fj import *
>>> b()
fj's a
Traceback (most recent call last):
  File "", line 1, in ?
  File "fj.py", line 6, in b
    foo()
NameError: global name 'foo' is not defined
Всё предсказуемо: зовётся a из нашего модуля, а foo не находится.
>>> def foo():
...   print "foo from outer scope"
... 
>>> b()
fj's a
Traceback (most recent call last):
  File "", line 1, in ?
  File "fj.py", line 6, in b
    foo()
NameError: global name 'foo' is not defined
Ага, foo опять не находится!
Это потому, что scope-ов много, по одному на code block. В частности, у модуля свой scope, имена в импортированном модуле разрешаются только в нём, а "выше", на уровень импортирующего, не заходят. Импортирующий же код не портит нечаянно имена в импортированном.
Но это не значит, что scope модуля нельзя поменять :)
>>> import fj
>>> fj.foo = foo
>>> b()
fj's a
foo from outer scope
Теперь, когда мы имеем удобное имя для модуля, мы лезем в его scope и вписываем туда имя своей функции. И всё срабатывает.
Сстановится вдруг понятно, почему, если 10 импортированных нами модулей вызывают в своём коде функцию a(), они получают каждый свою. И ясно, как подсунуть другую a().
>>> def not_a():
...   print "ceci n'est une a"
... 
>>> fj.a = not_a
>>> b()
ceci n'est une a
foo from outer scope
>>> _

Вот как-то так, мне кажется.

Мои извинения хозяину журнала, которому всё это приходит на почту %) 御免なさい!

[identity profile] faceted-jacinth.livejournal.com 2008-05-19 08:11 pm (UTC)(link)
Ух ты, да, я был неправ. Почему-то мне казалось, что функции должны быть ридонли.

По поводу импорта -- да, видимо так всё и работает. Я хотел сказать, что происходящее в процессе тоже не вполне укладывается в представление о питоне как о чисто скриптовом, с одной стороны импорт вроде бы просто исполняет модуль и добавляет его имя в локальный scope, с другой -- имеем это вот ровно двухкратное исполнение.
nine_k: A stream of colors expanding from brain (Default)

[personal profile] nine_k 2008-05-19 08:16 pm (UTC)(link)
Кстати сказать, пока я не порылся немного в спецификациях, я тоже думал, что я неправ, и готовился вежливо признать поражение :)

Да, если нужен ещё более "чисто скриптовый" — это, наверное, ruby в его исходной реализации, там напрямую по дереву ходят при исполнении (естетственно, это тормозит). В rubinius вроде сделали фазу компиляции во что-то (но не напрямую в байткод jvm).