Преимущества доступа к абстрактному синтаксическому дереву (AST). Как Джулия этим пользуется?

Я читал, что у Джулии есть доступ к AST кода, который она запускает. Что именно это означает? Это то, что среда выполнения может получить к нему доступ, сам код может получить к нему доступ, или и то, и другое?

Основываясь на этом:

  1. Это ключевое отличие Джулии от других динамических языков, в частности от Python?
  2. Каковы практические преимущества доступа к AST?

Что было бы хорошим примером того, что вам нелегко сделать на Python, но что вы можете сделать в Julia из-за этого?


person Amelio Vazquez-Reina    schedule 02.04.2014    source источник
comment
объекты кода Python не имеют прямого доступа к их AST для обратной компиляции. , но объекты AST Python можно скомпилировать в объекты кода, поэтому вы всегда можете ast.parse какой-нибудь источник и запустите его позже.   -  person kojiro    schedule 02.04.2014


Ответы (3)


Что отличает Julia от таких языков, как Python, так это то, что Julia позволяет вам перехватывать код до его оценки. Макросы - это просто функции, написанные на Julia, которые позволяют вам получить доступ к этому коду и манипулировать им до его запуска. Более того, вместо того, чтобы рассматривать код как строку (например, "f(x)"), он предоставляется как юлианский объект (например, Expr(:call, :f, :x)).

Это позволяет многое, что просто невозможно в Python. Основные из них:

Вы можете выполнять больше работы во время компиляции, увеличивая производительность

Два хороших примера - регулярные выражения и printf. Оба они принимают какую-то спецификацию формата и каким-то образом интерпретируют ее. Теперь их можно довольно просто реализовать в виде функций, которые могут выглядеть так:

match(Regex(".*"), str)
printf("%d", num)

Проблема в том, что эти спецификации должны интерпретироваться повторно каждый раз при запуске оператора. Каждый раз, когда интерпретатор проходит через этот блок, регулярное выражение должно быть повторно скомпилировано в конечный автомат, а формат должен выполняться через мини-интерпретатор. С другой стороны, если мы реализуем их как макросы:

match(r".*", str)
@printf("%d", num)

Затем макросы r и @printf перехватят код во время компиляции и запустят свои соответствующие интерпретаторы затем. Регулярное выражение превращается в быстрый конечный автомат, а оператор @printf превращается в простой println(num). Во время выполнения выполняется минимум работы, поэтому код работает быстро. Теперь другие языки могут предоставлять быстрые регулярные выражения, например, предоставляя для них специальный синтаксис, но тот факт, что они не привязаны к специальному регистру в Julia, означает, что разработчики могут использовать те же методы в своем собственном коде.

Вы можете делать мини-компиляторы для чего угодно

Языки с макросами, как правило, имеют более функциональные встроенные DSL, потому что вы можете изменять семантику языка по своему желанию. Например, язык алгебраического моделирования JuMP.jl. В Clojure также есть несколько интересных примеров, таких как встроенный язык логического программирования. Mathematica.jl даже встраивает семантику Mathematica в Julia, чтобы вы могли писать действительно естественно символьные выражения типа @Integrate(log(x), {x,0,2}). Вы можете подделать это до некоторой степени в Python (SymPy отлично справляется), но не так чисто и эффективно.

Если это вас не убеждает, подумайте, что кому-то удалось реализовать интерактивный отладчик Julia на чистом Julia. с помощью макросов. Попробуйте это на Python.

Изменить: Еще один замечательный пример того, что сложно на других языках - Cartestian.jl, который позволяет писать общие алгоритмы для массивов любого количества измерений.

person one-more-minute    schedule 02.04.2014

Я не знаком с Джулией и только впервые услышал об этом с вашим вопросом, но это звучало ужасно похоже на Лисп (и действительно, Джулия кажется новым внуком / диалектом Лиспа из того, что я читаю), и это мощные макросы. Возможность доступа к AST во время выполнения / компиляции привносит в код программистов совершенно новое измерение: метапрограммирование.

См. http://docs.julialang.org/en/latest/manual/metaprogramming/ и особенно http://docs.julialang.org/en/latest/manual/metaprogramming/#macros для некоторых практических целей. По сути, вы можете «вводить / изменять» код в тех местах, где python / R не может сделать то же самое.

person smassey    schedule 02.04.2014

Пример: развертывание цикла без копирования и вставки, для чего требуется аргумент времени компиляции, чтобы легко варьировать, насколько вы хотите развернуть цикл.

Вот отличный ресурс по метапрограммированию Джулии: https://en.wikibooks.org/wiki/Introduction_Julia/Metaprogramming

person saolof    schedule 24.09.2016