如何在Julia

时间:2016-03-29 17:34:04

标签: julia concatenative-language

我想在Julia中实现一个简单的连接语言(也就是Joy或Factor)作为DSL,我很困难如何最佳地表示堆栈。

表示数据和程序代码的堆栈应该能够容纳一系列不同类型的项目。在最简单的情况下,Ints,Symbols和递归地再次堆叠(表示引用的代码)。该程序将大量使用推!和流行!在不同的堆栈之间洗牌。

Julia中的一个明显的实现是使用单元格数组,但它运行起来却很慢。例如,以下Joy堆栈[ 1 [ 1 2 +] i + ](评估为[4])可以在Julia中实现 stack = Any[:+,:i,Any[:+,2,1],1]。我的典型代码如下所示:

x = pop!(callstack)
if isa(x,Int)
   push!(x,datastack)
elseif isa(x,Symbol)
   do_stuff(x,datastack)
end

然而,这运行速度非常慢并且使用了大量的内存分配,可能是因为这样的代码不是类型稳定的(这是Julia中的一个巨大的性能瓶颈)。

使用C,我将紧凑地表示堆栈作为联合的数组(或者作为链表):

typedef union Stackelem{
    int val;
    char *sym;
    union Stackelem *quote;
} Stackelem;

Stackelem stack[n];

但是如何在Julia中实现异构堆栈的这种紧凑表示,以及如何避免类型不稳定?

1 个答案:

答案 0 :(得分:3)

这是一种方式,另一种方式是表示类型为Vector {Any}的args:

julia> immutable Exp
          head::Symbol
          args::Tuple
       end

julia> q = Exp(:+, (1, Exp(:-, (3, 4))))
Exp(:+,(1,Exp(:-,(3,4))))

编辑:表示它的另一种方式可能是:

immutable QuoteExp{T} ; vec::Vector{T} ; end
typealias ExpTyp Union{QuoteExp, Int, Symbol}
typealias Exp QuoteExp{ExpTyp}

然后您可以执行以下操作:

julia> x = Exp(ExpTyp[:+, 1, 2])
QuoteExp{Union{Int64,QuoteExp{T},Symbol}}(Union{Int64,QuoteExp{T},Symbol}[:+,1,2])
julia> x.vec[1]
:+
julia> x.vec[2]
1
julia> x.vec[3]
2
julia> push!(x.vec,:Scott)
4-element Array{Union{Int64,QuoteExp{T},Symbol},1}:
  :+    
 1      
 2      
  :Scott
julia> x.vec[4]
:Scott