Julia中的“符号”是什么?
具体来说:我试图使用Julia的DataFrames包,特别是带有名称选项的readtable()函数,但是这需要一个符号向量。
- 什么是符号?
- 为什么他们会select一个string的vector?
到目前为止,我只发现了一些Julia语言中符号的引用。 看起来符号是用“:var”表示的,但是对于我来说,它们是什么都不清楚。
旁白:我可以跑
df = readtable( "table.txt", names = [symbol("var1"), symbol("var2")] )
我的两个问题依然存在。
Julia中的符号与Lisp,Scheme或Ruby中的符号相同。 但是,我认为这些相关问题的答案 并不令人满意 。 如果你阅读这些答案,似乎符号不同于string的原因是string是可变的,而符号是不可变的,而符号也是“被实施的” – 无论如何。 Ruby和Lisp中的string是可变的,但是它们不在Julia中,而这个差别实际上是一个红色的鲱鱼。 符号被实现的事实 – 即通过快速平等比较的语言实现而被哈希 – 也是不相关的实现细节。 你可以有一个不实习符号的实现,语言也是完全一样的。
那么什么是符号呢? 答案就在于Julia和Lisp有共同之处 – 将语言的代码表示为语言本身的数据结构的能力。 有些人称之为“同心性” ( 维基百科 ),但其他人似乎并不认为单独一个语言就足以使其成为同心圆。 但是术语并不重要。 关键是当一个语言可以表示自己的代码时,它需要一种方法来表示分配,函数调用,可以写成文字值的东西等等。它还需要一种方法来表示自己的variables。 也就是说,你需要一种方式来表示 – 作为数据 – 左边的foo
:
foo == "foo"
现在我们来谈谈问题的核心:符号和string之间的区别在于比较左侧的"foo"
和右侧的"foo"
之间的区别。 在左侧, foo
是一个标识符,它的值是当前范围内的variablesfoo
的值。 在右边, "foo"
是一个string文字,它的计算结果是string值“foo”。 Lisp和Julia中的一个符号就是如何将一个variables表示为数据。 一个string只是代表自己。 你可以通过应用eval
来看到它们的区别:
julia> eval(:foo) ERROR: foo not defined julia> foo = "hello" "hello" julia> eval(:foo) "hello" julia> eval("foo") "foo"
符号:foo
计算取决于什么 – 如果有的话 – variablesfoo
绑定,而"foo"
总是只计算为“foo”。 如果你想在Julia中构造使用variables的expression式,那么你使用的是符号(无论你是否知道)。 例如:
julia> ex = :(foo = "bar") :(foo = "bar") julia> dump(ex) Expr head: Symbol = args: Array{Any}((2,)) 1: Symbol foo 2: String "bar" typ: Any
除了别的东西之外,抛出东西的东西是,在引用代码foo = "bar"
的expression式对象中有一个:foo
符号对象。 下面是另外一个例子,用符号:foo
存储在variablessym
构build一个expression式:
julia> sym = :foo :foo julia> eval(sym) "hello" julia> ex = :($sym = "bar"; 1 + 2) :(begin foo = "bar" 1 + 2 end) julia> eval(ex) 3 julia> foo "bar"
如果当sym
被绑定到string"foo"
时试图做到这一点,它将不起作用:
julia> sym = "foo" "foo" julia> ex = :($sym = "bar"; 1 + 2) :(begin "foo" = "bar" 1 + 2 end) julia> eval(ex) ERROR: syntax: invalid assignment location ""foo""
很明显,为什么这不起作用 – 如果您试图手动指定"foo" = "bar"
,它也不起作用。
这是符号的本质:符号用于表示元编程中的variables。 一旦将符号当作数据types,当然,将它们用于其他事物就变得很诱人,如散列键。 但是,这是偶然的,机会主义的使用另一个主要目的的数据types。
请注意,我停止谈论Ruby。 这是因为Ruby不同心:Ruby不会将其expression式表示为Ruby对象。 所以Ruby的符号types是一种退化的器官 – 一个遗留的适应,从Lispinheritance,但不再用于它的原始目的。 为了其他目的,Ruby符号已经被选作其他用途 – 作为哈希键,将方法从方法表中抽出 – 但Ruby中的符号不被用来表示variables。
至于为什么在DataFrames中使用符号而不是在string中使用符号,这是因为DataFrames中的一个常见模式是将列值绑定到用户提供的expression式中的variables。 所以列名是符号是很自然的,因为符号正是你用来表示variables的数据。 目前,您必须编写df[:foo]
才能访问foo
列,但是将来您可能会将其作为df.foo
来访问。 当这成为可能的时候,只有名称是有效标识符的列才能用这个方便的语法访问。
也可以看看:
- https://docs.julialang.org/en/latest/manual/metaprogramming/
- Elixir和Julia homoiconic等语言在某种程度上是什么意思?