什么是“符号"?在朱莉娅? [英] What is a "symbol" in Julia?

查看:102
本文介绍了什么是“符号"?在朱莉娅?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具体来说: 我正在尝试使用Julia的DataFrames包,特别是使用带有names选项的readtable()函数,但这需要一个符号向量.

Specifically: I am trying to use Julia's DataFrames package, specifically the readtable() function with the names option, but that requires a vector of symbols.

  • 什么是符号?
  • 为什么他们会选择一个字符串向量作为对象?

到目前为止,我只发现了少量的茱莉亚语中的符号"一词的引用.似乎符号用:var"表示,但是我对它们的含义还很不清楚.

So far I have found only a handful of references to the word symbol in the Julia language. It seems that symbols are represented by ":var", but it is far from clear to me what they are.

除了: 我可以跑步

df = readtable( "table.txt", names = [symbol("var1"), symbol("var2")] )

我的两个项目符号问题仍然存在.

My two bulleted questions still stand.

推荐答案

Julia中的符号与Lisp,Scheme或Ruby中的符号相同.但是,这些问题的答案 并不十分令人满意.如果您阅读了这些答案,似乎符号与字符串不同的原因是字符串是可变的,而符号是不可变的,并且符号也是"interned"的(无论如何).字符串确实在Ruby和Lisp中是可变的,但是在Julia中却不是,并且这种区别实际上是一个红色的鲱鱼.插入符号的事实-即由语言实现进行哈希处理以进行快速相等比较-也是无关紧要的实现细节.您可以实现不使用符号的实现,并且语言也将完全相同.

Symbols in Julia are the same as in Lisp, Scheme or Ruby. However, the answers to those related questions are not really satisfactory, in my opinion. If you read those answers, it seems that the reason a symbol is different than a string is that strings are mutable while symbols are immutable, and symbols are also "interned" – whatever that means. Strings do happen to be mutable in Ruby and Lisp, but they aren't in Julia, and that difference is actually a red herring. The fact that symbols are interned – i.e. hashed by the language implementation for fast equality comparisons – is also an irrelevant implementation detail. You could have an implementation that doesn't intern symbols and the language would be exactly the same.

那么什么是符号,真的吗?答案在于Julia和Lisp的共同点-能够将语言代码表示为语言本身的数据结构.有人将此称为同性恋" (

So what is a symbol, really? The answer lies in something that Julia and Lisp have in common – the ability to represent the language's code as a data structure in the language itself. Some people call this "homoiconicity" (Wikipedia), but others don't seem to think that alone is sufficient for a language to be homoiconic. But the terminology doesn't really matter. The point is that when a language can represent its own code, it needs a way to represent things like assignments, function calls, things that can be written as literal values, etc. It also needs a way to represent its own variables. I.e., you need a way to represent – as data – the foo on the left hand side of this:

foo == "foo"

现在,我们进入问题的核心:符号和字符串之间的差异是该比较左侧的foo与右侧的"foo"之间的差异.在左侧,foo是一个标识符,其计算结果是绑定到当前作用域中的变量foo的值.在右侧,"foo"是字符串文字,其计算结果为字符串值"foo". Lisp和Julia中的符号是如何将变量表示为数据.字符串只是代表自己.您可以通过对它们应用eval来看到差异:

Now we're getting to the heart of the matter: the difference between a symbol and a string is the difference between foo on the left hand side of that comparison and "foo" on the right hand side. On the left, foo is an identifier and it evaluates to the value bound to the variable foo in the current scope. On the right, "foo" is a string literal and it evaluates to the string value "foo". A symbol in both Lisp and Julia is how you represent a variable as data. A string just represents itself. You can see the difference by applying eval to them:

julia> eval(:foo)
ERROR: foo not defined

julia> foo = "hello"
"hello"

julia> eval(:foo)
"hello"

julia> eval("foo")
"foo"

符号:foo的计算结果取决于变量foo所绑定的对象(如果有的话),而"foo"始终仅计算为"foo".如果要在Julia中构造使用变量的表达式,则使用符号(无论您是否知道).例如:

What the symbol :foo evaluates to depends on what – if anything – the variable foo is bound to, whereas "foo" always just evaluates to "foo". If you want to construct expressions in Julia that use variables, then you're using symbols (whether you know it or not). For example:

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"获得的表达式对象内部有一个:foo符号对象.这是另一个示例,使用存储在变量sym中的符号:foo构造表达式:

What that dumped out stuff shows, among other things, is that there's a :foo symbol object inside of the expression object you get by quoting the code foo = "bar". Here's another example, constructing an expression with the symbol :foo stored in the variable sym:

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绑定到字符串"foo"时尝试执行此操作,则它将无效:

If you try to do this when sym is bound to the string "foo", it won't work:

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",它也将不起作用.

It's pretty clear to see why this won't work – if you tried to assign "foo" = "bar" by hand, it also won't work.

这是符号的本质:符号用于表示元编程中的变量.当然,一旦将符号作为数据类型,就很容易将它们用于其他用途,例如哈希键.但这是偶然的,机会主义的数据类型使用,它具有另一个主要目的.

This is the essence of a symbol: a symbol is used to represent a variable in metaprogramming. Once you have symbols as a data type, of course, it becomes tempting to use them for other things, like as hash keys. But that's an incidental, opportunistic usage of a data type that has another primary purpose.

请注意,不久前我不再谈论Ruby.那是因为Ruby不是谐音的:Ruby没有将其表达式表示为Ruby对象.因此,Ruby的符号类型有点像是一种残余器官-一种残留的改编,继承自Lisp,但不再用于其原始用途.已将Ruby符号用于其他目的-作为哈希键,以将方法从方法表中拉出-但是Ruby中的符号不​​用于表示变量.

Note that I stopped talking about Ruby a while back. That's because Ruby isn't homoiconic: Ruby doesn't represent its expressions as Ruby objects. So Ruby's symbol type is kind of a vestigial organ – a leftover adaptation, inherited from Lisp, but no longer used for its original purpose. Ruby symbols have been co-opted for other purposes – as hash keys, to pull methods out of method tables – but symbols in Ruby are not used to represent variables.

关于为什么在DataFrames中使用符号而不是在字符串中使用符号的原因,是因为这是DataFrames中将列值绑定到用户提供的表达式内的变量的一种常见模式.因此,列名自然是符号,因为符号正是您用来将变量表示为数据的符号.当前,您必须编写df[:foo]才能访问foo列,但是将来,您也许可以使用df.foo来访问它.如果可能,使用这种方便的语法只能访问名称为有效标识符的列.

As to why symbols are used in DataFrames rather than strings, it's because it's a common pattern in DataFrames to bind column values to variables inside of user-provided expressions. So it's natural for column names to be symbols, since symbols are exactly what you use to represent variables as data. Currently, you have to write df[:foo] to access the foo column, but in the future, you may be able to access it as df.foo instead. When that becomes possible, only columns whose names are valid identifiers will be accessible with this convenient syntax.

另请参见:

  • https://docs.julialang.org/en/latest/manual/metaprogramming/
  • In what sense are languages like Elixir and Julia homoiconic?

这篇关于什么是“符号"?在朱莉娅?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆