Стабильность типов позволяет компилятору определять типы вывода функции непосредственно из типов ввода во время компиляции.Поскольку Джулия специализируется на компиляции для каждого входного типа, это означает, что, если все функции являются стабильными по типу, компилятор может определить типы каждого значения внутри вызова функции.Когда это происходит, JIT-компилятор Джулии по существу создает статически типизированную версию метода и создает IR LLVM для компиляции этой статической версии, где эта статическая версия, по сути, является тем же кодом сборки, что и C, скомпилированный с помощью clang (LLVM).
Это означает, что если компилятор может определять базовые типы для каждой переменной, он будет выдавать код, который заставляет эти типы содержать, как если бы он был полностью аннотированным C-кодом.Способ, которым Julia является динамическим, заключается в том, что, когда это не выполняется, тогда он «упаковывает» переменные, по существу, создает новый тип, который говорит: «Я не знаю, что это за тип», и добавляет код для принудительной проверки типов.и отправлять вычисления во время выполнения для обработки динамичности.Таким образом, если вся информация о типах известна, динамичность Юлии компилируется и перестает существовать даже в исполняемом коде.
Именно поэтому множественная диспетчеризация так важна для языка, поскольку множественная диспетчеризация означает, что f(x)
имеет другой метод для f(x::Float64)
(даже если вы не укажете конкретную версию, компиляторбудет выводить и использовать это, называемое автоматической специализацией типа), и теперь эта конкретная версия будет более стабильной, чем общая версия.Предоставление множественной диспетчеризации как функции на самом деле просто позволяет вам перехватить этот этап компиляции и разрешить изменение отношения type-> code.