Я думаю (слишком долго для комментария, поэтому я даю его в качестве ответа), что в этом случае, вероятно, лучше быть нестабильным. Обратите внимание, что именно это и делает сама Джулия:
julia> x = :(1+2*(3+4))
:(1 + 2 * (3 + 4))
julia> dump(x)
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Int64 1
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol *
2: Int64 2
3: Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol +
2: Int64 3
3: Int64 4
Конечно, у Джулии значительно более богатый синтаксис, но даже в вашем простом случае учтите следующее. Вы получаете преимущества стабильности типов, если один раз скомпилируете некоторую часть кода, а затем многократно запускаете ее (в той или иной форме).
Теперь я предполагаю, что написанное вами будет оцениваться на практике в основном только одним время. Если вы сделали ваши выражения полностью стабильными, вы должны будете платить каждый раз (при условии, что выражение меняется):
- стоимость его компиляции (дорого)
- стоимость его запуска (относительно дешево)
Если ваш код будет нестабильным, вам придется оплатить стоимость компиляции только один раз. Это правда, что запуск будет немного медленнее, но в целом, вероятно, будет лучше сделать это следующим образом.
С другой стороны - если вы ожидаете, что вы определите выражение только один раз, а затем запустите его во многих случаях, возможно, лучше использовать метапрограммирование:
- обрабатывает ваше выражение только один раз и генерирует код Джулии, который будет оценивать ваше выражение
- затем Джулия скомпилирует сгенерированный код, как только
- вы получите максимальную производительность при его выполнении после выполнения шагов 1 и 2
Полумера к вашему вопросу будет использовать следующую структуру данных:
struct Binary{T <: BinaryKind, S} <: Operation
xs::Vector{S}
end
Таким образом, ваш код будет устойчивым к типам, если S
является конкретным типом или небольшим объединением конкретных типов, и нестабильным типом в противном случае (и я ожидаю, что тогда вы можете попытаться заставить остальную часть кода сгенерировать xs
таким образом, чтобы eltype
был конкретным или небольшим объединением конкретных типов).
(если вы Есть еще вопросы по этому вопросу, пожалуйста, прокомментируйте, и я могу расширить ответ)