Что отличает 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.parse
какой-нибудь источник и запустите его позже. - person kojiro   schedule 02.04.2014