Если смотреть на высокоуровневую часть «многого» — да, там динамики не много. Но чтобы эта высокоуровневое «много» заработало, используется довольно много низкоуровневых вещей, построенных именно на динамике. В принципе, нет никаких принципиальных преград тому, чтобы переписать эти низкоуровневые вещи без динамики под компиляцию, но это уже объем работ существенно больший, нежели просто написание компилятора.
Почему никто принципиально не хочет писать компилятор для Python?
Модератор: Модераторы разделов
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
А зачем делать eval для машкода? Если же ты сам вызывашь eval в своей программе, то естественно она попадет в конечный образ со всеми вытекающими.
Зачем? Не придется
(© '(define LISP (такой язык-программирования (состоящий-из смайликов (чуть более) (чем целиком)))) lurkmore)
Re: Почему никто принципиально не хочет писать компилятор для Python?
korvin, интересно как Вы избавитесь от интерпретатора, если, например, строка, которая должна быть передана в eval получена от пользователя?
Re: Почему никто принципиально не хочет писать компилятор для Python?
korvin писал(а): ↑11.02.2012 10:12
А зачем делать eval для машкода? Если же ты сам вызывашь eval в своей программе, то естественно она попадет в конечный образ со всеми вытекающими.
в момент компиляции весьма проблематично узнать что именно будет/должно происходить в eval
Re: Почему никто принципиально не хочет писать компилятор для Python?
Я же сказал, если в программе есть прямой или косвенный вызов eval, то естественно, все, что для него нужно, попадет в скомпилированный образ. В противном случае компилятор может выкинуть все, что не нужно.
http://www.cliki.net/Creating%20Executables
Конечно есть определенная сложность, но принципиальная невозможность выкинуть eval/compile отсутствует.
http://www.cliki.net/Creating%20Executables
"Tree-shaking" functionality, in principle, can reduce the size of a Lisp executable by excising the compiler or debugger, but this severely reduces the flexibility of the program; the compiler and debugger are handy to interactively and remotely patch the running system on the recipient's machine. Also, the compiler is used in some implementations at unexpected times, for instance, within the CLOS implementation, making tree-shaking somewhat impractical.
Конечно есть определенная сложность, но принципиальная невозможность выкинуть eval/compile отсутствует.
(© '(define LISP (такой язык-программирования (состоящий-из смайликов (чуть более) (чем целиком)))) lurkmore)
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
В динамических языках, вроде Python, очень тяжело выяснить, что нужно, даже без eval. Простой пример:
Код: Выделить всё
#!/usr/bin/python
def cmd_a():
print 'Executing subcommand "a"'
def cmd_b():
print 'Executing subcommand "b"'
def _main(argv):
globals()['cmd_' + argv[1]]()
if __name__ == '__main__':
import sys
sys.exit(_main(sys.argv))
И это только про используется/не используется. А как быть компилятору (настоящему, а не JIT) с создаваемыми на лету классами?
Так что, максимум, чего можно ожидать для Python, это JIT compiler a-la V8 для JS. Непонятно, кстати, почему его еще не сделали, а продолжают пилить это нынешнее тормозилово.
Мои розовые очки
- /dev/random
- Администратор
- Сообщения: 5289
- ОС: Gentoo
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑01.03.2012 23:59Так что, максимум, чего можно ожидать для Python, это GIT compiler a-la V8 для JS. Непонятно, кстати, почему его еще не сделали, а продолжают пилить это нынешнее тормозилово.
Сделали. PyPy. Работатет чуть быстрее, но потребляет заметно больше памяти.
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑01.03.2012 23:59В динамических языках, вроде Python, очень тяжело выяснить, что нужно, даже без eval. Простой пример:
Как компилятор может определить, что cmd_a() и cmd_b() используются и их не надо выкидывать из результирующего бинарника?Код: Выделить всё
#!/usr/bin/python def cmd_a(): print 'Executing subcommand "a"' def cmd_b(): print 'Executing subcommand "b"' def _main(argv): globals()['cmd_' + argv[1]]() if __name__ == '__main__': import sys sys.exit(_main(sys.argv))
А где они используются?
(© '(define LISP (такой язык-программирования (состоящий-из смайликов (чуть более) (чем целиком)))) lurkmore)
- /dev/random
- Администратор
- Сообщения: 5289
- ОС: Gentoo
Re: Почему никто принципиально не хочет писать компилятор для Python?
Здесь:
Код: Выделить всё
def _main(argv):
globals()['cmd_' + argv[1]]()
вызывается без параметров глобальная функция с именем cmd_X, где X - текст, введённый пользователем как первый аргумент командной строки при запуске программы.
Re: Почему никто принципиально не хочет писать компилятор для Python?
Наверное JIT или я чего-то не знаю?
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Ага, просто пальчики уже сами набирают git :)
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑01.03.2012 23:59В динамических языках, вроде Python, очень тяжело выяснить, что нужно, даже без eval. Простой пример:
Как компилятор может определить, что cmd_a() и cmd_b() используются и их не надо выкидывать из результирующего бинарника? Как компилятор может определить, нужен модуль sys или не нужен? А если вместо стандарной идиомы if __name__ == '__main__' используется какое-нибудь более заковыристое условие? А если вместо import sys используется __import__() с хитро сгенерированным именем модуля?Код: Выделить всё
#!/usr/bin/python def cmd_a(): print 'Executing subcommand "a"' def cmd_b(): print 'Executing subcommand "b"' def _main(argv): globals()['cmd_' + argv[1]]() if __name__ == '__main__': import sys sys.exit(_main(sys.argv))
Кстати как раз вот этот момент довольно просто реализуется:
1. Не выбрасывать ничего. Ну, будет больше места занимать, возможно частично неиспользуемый код.
2. Модули пусть в зависимостях пакета разработчики выставляют. А сами модули — отдельной либой.
watashiwa_daredeska писал(а): ↑01.03.2012 23:59И это только про используется/не используется. А как быть компилятору (настоящему, а не JIT) с создаваемыми на лету классами?
Вот это уже на порядок сложнее, но основная трудность сводится к тому же eval и необходимости тащить компилятор.
watashiwa_daredeska писал(а): ↑01.03.2012 23:59Так что, максимум, чего можно ожидать для Python, это JIT compiler a-la V8 для JS. Непонятно, кстати, почему его еще не сделали, а продолжают пилить это нынешнее тормозилово.
Для JS основным стимулом была гонка браузеров, а потом пошли тяжеловесные web-приложения (политика Google, в первую очередь, о переносе всего в сеть), которые стали новой целью для гонки. А для Python ничего такого нет. Нет конкурренции.
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
eval'ом тут и не пахнет. В Python'е это делается вполне штатно без всякого eval.
Навалом конкуренции. В зависимости от областей применения — Ruby, Perl, Lua, да тот же JS в лице Node.JS. Это только из чисто скриптовых. А сколько еще всякой лабуды написано на каких-нибудь компилируемых языках только потому, что Python'а чуток не хватает по скорости. А сделай его раза в 2-3 пошустрее, и окажется, что в некоторых случаях можно и от какой-нибудь Java отказаться.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
/dev/random писал(а): ↑02.03.2012 00:37
Здесь:
Код: Выделить всё
def _main(argv): globals()['cmd_' + argv[1]]()
вызывается без параметров глобальная функция с именем cmd_X, где X - текст, введённый пользователем как первый аргумент командной строки при запуске программы.
Ну дык очевидно, что неявный вызов eval есть, через globals или читайте ниже.
(© '(define LISP (такой язык-программирования (состоящий-из смайликов (чуть более) (чем целиком)))) lurkmore)
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑02.03.2012 11:48eval'ом тут и не пахнет. В Python'е это делается вполне штатно без всякого eval.
Навалом конкуренции. В зависимости от областей применения — Ruby, Perl, Lua, да тот же JS в лице Node.JS. Это только из чисто скриптовых. А сколько еще всякой лабуды написано на каких-нибудь компилируемых языках только потому, что Python'а чуток не хватает по скорости. А сделай его раза в 2-3 пошустрее, и окажется, что в некоторых случаях можно и от какой-нибудь Java отказаться.
Дык значит eval'а и не будет, будет, например, apply, или что у Вас там отвечает за вызов функции по имени. Только apply требует eval для вычисления значений аргументов. Вы не забывайте, что я говорил про косвенные вызовы. Необходимость в eval определяется вовсе не синтаксически, то, что вы его не видите, не значит, что он есть. В вашем примере он, кстати, не нужен.: поиск функции по имени не требует eval.
(© '(define LISP (такой язык-программирования (состоящий-из смайликов (чуть более) (чем целиком)))) lurkmore)
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
И что по вашему такое eval? Потому что с формальной точки зрения в моем примере eval'а нет, есть исключительно штатная работа с объектами Python. globals() — это dict() и никакой eval-магии.
Не требует. Вот пожалуйста использование apply:
Код: Выделить всё
def Fadd2(f):
def Adder(*args, **kw):
return f(*args, **kw) + 2
return Adder
А компилятору от этого легче? Вот пример:
Код: Выделить всё
def Inc(self, x):
self.counter = getattr(self, 'counter', 0) + x
def Dec(self, x):
self.counter = getattr(self, 'counter', 0) - x
Counter = type(
'Counter',
(),
{
'Inc': Inc,
'Dec': Dec,
})
counter = Counter()
counter.Inc(2)
print counter.counter
counter.Dec(1)
print counter.counter
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑02.03.2012 11:48eval'ом тут и не пахнет. В Python'е это делается вполне штатно без всякого eval.
Ну, тогда это совсем не трудность. Сделать обёртку на основе map/hash строка→указатель на функцию и почти все проблемы решаются. Я думал, что методы формируются динамически из строк, а если нет, то сложности нет.
watashiwa_daredeska писал(а): ↑02.03.2012 11:48Навалом конкуренции. В зависимости от областей применения — Ruby, Perl, Lua, да тот же JS в лице Node.JS. Это только из чисто скриптовых. А сколько еще всякой лабуды написано на каких-нибудь компилируемых языках только потому, что Python'а чуток не хватает по скорости. А сделай его раза в 2-3 пошустрее, и окажется, что в некоторых случаях можно и от какой-нибудь Java отказаться.
Это не та конкурренция. Внутри Python её нет, как это в случае JS. Да и скорость всех этих языков, кроме JS оставляет желать лучшего. А JS пилят и пилят.
watashiwa_daredeska писал(а): ↑04.03.2012 19:58А компилятору от этого легче? Вот пример:На лету создается класс Counter с методами Inc и Dec. Без всякого eval.Код: Выделить всё
def Inc(self, x): self.counter = getattr(self, 'counter', 0) + x def Dec(self, x): self.counter = getattr(self, 'counter', 0) - x Counter = type( 'Counter', (), { 'Inc': Inc, 'Dec': Dec, }) counter = Counter() counter.Inc(2) print counter.counter counter.Dec(1) print counter.counter
Да, легче, тут нет никаких особых проблем для компиляции. Да, вызов методов будет медленнее, чем даже виртуальных. Но тем не менее.
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
ORLY? Если Вы «в лоб» сделаете «компиляцию» со всеми этими hash'ами, которые использует питон, со string lookup при каждом вызове и т.п., то не получите практически никакого профита — это и есть «притащить весь интерпретатор», только фаза декодирования команд байт-кода будет выброшена, а вот собственно их исполнение получится ровно то же в полный рост, с теми же проблемами. Т.е. это будет ни разу не та же самая компиляция, что у C или даже у Go.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑04.03.2012 23:22ORLY? Если Вы «в лоб» сделаете «компиляцию» со всеми этими hash'ами, которые использует питон, со string lookup при каждом вызове и т.п., то не получите практически никакого профита — это и есть «притащить весь интерпретатор», только фаза декодирования команд байт-кода будет выброшена, а вот собственно их исполнение получится ровно то же в полный рост, с теми же проблемами. Т.е. это будет ни разу не та же самая компиляция, что у C или даже у Go.
Да, сам код будет скомпилирован, поэтому интерпретатор тащить не надо. Динамически созданные классы будут медленнее в вызовах, естественно (но они же не 100% кода покрывают). Если знакомы с COM (да-да, MS, поверх которой сделаны OLE, ActiveX), то там есть т.н. IDispatch, который реализует вот то, о чём говорим. Плюс можно ускорить статические вызовы динамических классов до уровня обычного/виртуального вызова. Ну, а если динамический вызов — тут трудно что-то придумать. Всё равно по хешу поиск делать как ни крути.
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
А как компилятор отличит динамически созданный класс от не динамически созданного? Приведенный выше код, когда класс изначально создается динамически — лишь часть проблемы, потому что можно изначально не динамический класс манки-патчить.
Всё, что Вы написали, в принципе верно, но… Нереализуемо средствами статического компилятора, ибо в Python, с его динамичностью, никогда нельзя сказать, динамический класс или статический, манки-патчит его кто-нибудь где-нибудь в другом месте программы или нет. Аналогично с функциями — никогда нельзя соптимизировать функцию под определенные типы аргументов, потому что невозможно статически заранее определить, с какими аргументами функция может быть вызвана. Т.е. все описанные Вами техники — это хорошо, и даже реализуемо компиляторами, но только JIT.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑05.03.2012 01:01Т.е. все описанные Вами техники — это хорошо, и даже реализуемо компиляторами, но только JIT.
Ну, да, элементы JIT будут присутствовать. Но я не называл бы это JIT-компиляцией. Код уже скомпилирован. А это оптимизации аналогичные отложенной загрузке и т.п. Код будет патчиться на лету, но не повсеместно, а только вызовы функций.
PS по поводу как отличить статический от динамического — у компилятора эта информация будет. А если её нет, значит динамический. Логично?
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Как? Как можно скомпилировать, например, функцию:
Код: Выделить всё
def Func(a, b):
return a.param + b;
Логично. В таком случае динамическими будут все классы до единого.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑05.03.2012 02:26Как? Как можно скомпилировать, например, функцию:? Об этой функции не известно вообще ничего. Ни что такое "a", ни "b", ни "a.param", ни что такое "+" для них.Код: Выделить всё
def Func(a, b): return a.param + b;
Вот валидный код на C++11.
Код: Выделить всё
template <class T1, class T2>
auto Func(T1 a, T2 b) -> decltype(a.param+b)
{
return a.param+b;
}
Нормально компилируется. Да, я понимаю, что это не охватит все вызовы, из-за динамичности Python. Для них будет сгенерировано что-то вроде:
1. Взять "param" у объекта "a". Обращение к хэшу.
2. Вызвать функцию "+", соответствующую типам "a.param" и "b". Тут не знаю как в Python с перегрузкой операторов.
watashiwa_daredeska писал(а): ↑05.03.2012 02:26Логично. В таком случае динамическими будут все классы до единого.
Нет. Не все типы ведь там неизвестные?
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Это НЕ аналог.
Код: Выделить всё
class A(object):
pass
class B(object):
def __add__(self, other):
return self.param + getattr(other, 'param', other)
def Func(a, b):
return a.param + b;
A.param = 'A'
a = A()
a.param = 'a'
f = lambda: None
f.param = 'f'
b = B()
b.param = B()
b.param.param = 'b.param'
B.param = 'B'
args = [
(A, '1'),
(a, '2'),
(B, '3'),
(b, '4'),
(b, f),
(b, B),
]
def MapApply(func, argiter):
return [func(*arg) for arg in argiter]
print MapApply(Func, args)
Мои розовые очки
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Для статического компилятора — все, за очень редким исключением.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑05.03.2012 04:28В этом случае Func передается как аргумент (в MapApply) и принимает аргументы разных типов (из списка args). Шаблоны C++ тут не канают — как аргумент можно передать только полную специализацию шаблона, но в этом случае переданная функция уже не сможет обрабатывать аргументы разных, заранее неизвестных типов.
Там же ниже я написал, что для неизвестных случаев будет работа с хешем.
watashiwa_daredeska писал(а): ↑05.03.2012 08:37Для статического компилятора — все, за очень редким исключением.
Возможно. Поскольку с Python не знаком, тут мне трудно будет ответить, хотя и кажется, что не так всё печально, как Вы говорите (Это же не Perl, где компилятор принципиально невозможен).
Конечно, элементы динамики придётся вносить для оптимизаций, но написать компилятор, имхо, возможно. Хотя и 100% согласен, что не нужно.
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
С т.з. компиляции Python и Perl практически идентичны.
Мои розовые очки
Re: Почему никто принципиально не хочет писать компилятор для Python?
watashiwa_daredeska писал(а): ↑05.03.2012 19:38С т.з. компиляции Python и Perl практически идентичны.
Не, различаются. Perl невозможно даже синтаксически разобрать. В Python такого нет.
Re: Почему никто принципиально не хочет писать компилятор для Python?
как это невозможен?
очень даже·
вот только работает полученный бинарник _так_ медленно, что ой…
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Почему никто принципиально не хочет писать компилятор для Python?
Ну, для компиляции Perl вполне можно разобрать. В приведенном примере:
Код: Выделить всё
whatever / 25 ; # / ; die "this dies!";
Мои розовые очки