Julia의 "기호"란 무엇입니까?


131

구체적으로 : Julia의 DataFrames 패키지, 특히 names 옵션과 함께 readtable () 함수를 사용하려고하지만 심볼 벡터가 필요합니다.

  • 상징은 무엇입니까?
  • 왜 그들은 벡터로 문자열을 선택했을까요?

지금까지 줄리아 언어의 단어 기호에 대한 소수의 참조 만 발견했습니다. 기호는 ": var"로 표시되는 것 같지만, 그것이 무엇인지는 분명하지 않습니다.

옆으로 : 나는 달릴 수있다

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

내 두 글 머리 기호는 여전히 유효합니다.


3
이 주제에 대한 몇 가지 대화는 여기에서 찾을 수 있습니다 : groups.google.com/d/msg/julia-users/MS7KW8IU-0o/cQ-yDOs_CQEJ을
jverzani

답변:


231

Julia의 기호는 Lisp, Scheme 또는 Ruby와 동일합니다. 그러나 대답 그 관련 질문은 정말 만족스럽지 제 생각에. 이 답변을 읽으면 기호가 문자열과 다른 이유는 문자열은 변경할 수 있고 기호는 변경할 수없고 기호도 "인터 닝"되기 때문입니다. 루비와 리스프에서는 문자열을 변경할 수 있지만 줄리아에는 없지만 그 차이는 실제로 붉은 청어입니다. 빠른 등식 비교를 위해 언어 구현에 의해 해시 된 기호가 서로 연결되어 있다는 사실도 관련이없는 구현 세부 사항입니다. 인턴 심볼이 아닌 구현이있을 수 있으며 언어는 정확히 동일합니다.

실제로 상징은 무엇입니까? 대답은 Julia와 Lisp가 공통적으로 가지고있는 것, 즉 언어 코드를 언어 자체의 데이터 구조로 표현할 수있는 능력에 있습니다. 어떤 사람들은 이것을 "동성애" ( 위키 백과 ) 라고 부르지 만, 어떤 사람들 은 언어 만 동성애자로 충분하다고 생각하지 않는 것 같습니다. 그러나 용어는 실제로 중요하지 않습니다. 요점은 언어가 자체 코드를 나타낼 수있을 때 할당, 함수 호출, 리터럴 값으로 쓸 수있는 것 등을 표현할 수있는 방법이 필요하다는 것입니다. 또한 고유 변수를 나타내는 방법도 필요합니다. 즉, foo왼쪽에서 데이터를 나타내는 방법이 필요합니다 .

foo == "foo"

이제 우리는 문제의 핵심에 도달했습니다. 심볼과 문자열의 차이는 foo비교의 왼쪽과 "foo"오른쪽의 차이입니다. 왼쪽 foo에는 식별자 foo가 있으며 현재 범위 의 변수 에 바인딩 된 값으로 평가됩니다 . 오른쪽 "foo"에는 문자열 리터럴이 있으며 문자열 값 "foo"로 평가됩니다. Lisp와 Julia의 심볼은 변수를 데이터로 표현하는 방법입니다. 문자열은 단지 그 자체를 나타냅니다. eval그들에게 적용하여 차이점을 볼 수 있습니다 .

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

julia> foo = "hello"
"hello"

julia> eval(:foo)
"hello"

julia> eval("foo")
"foo"

심볼이 :foo평가하는 것은 변수 foo가 무엇 에 바인딩되어 있는지에 따라 다르지만 "foo"항상 "foo"로 평가됩니다. 변수를 사용하는 Julia에서 표현식을 구성하려면 기호를 알고 있는지 여부를 알 수 있습니다. 예를 들면 다음과 같습니다.

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코드를 인용하여 얻은 표현식 객체 안에 기호 객체 가 있다는 것 foo = "bar"입니다. 다음 :foo은 변수에 저장된 기호로 표현식을 구성하는 또 다른 예입니다 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"

symstring에 바인딩되어 있을 때이 작업을 수행하려고하면 "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"하지 않는지 알 수 있습니다. 직접 할당하려고 시도해 도 작동하지 않습니다.

이것이 상징의 본질입니다. 상징은 메타 프로그래밍에서 변수를 나타내는 데 사용됩니다. 물론 데이터 유형으로 기호가 있으면 해시 키와 같은 다른 용도로 기호를 사용하는 것이 좋습니다. 그러나 이것은 또 다른 주요 목적을 가진 데이터 유형의 우발적, 기회 적 사용입니다.

루비에 대한 이야기는 잠시 중단되었습니다. Ruby가 동 질적이지 않기 때문입니다. Ruby는 해당 표현식을 Ruby 객체로 나타내지 않습니다. 따라서 루비의 심볼 유형은 일종의 흔적 기관입니다. 남은 부분은 Lisp에서 상속되었지만 더 이상 원래 목적으로 사용되지 않았습니다. 루비 심볼은 해시 키와 같은 다른 목적으로 메소드 테이블에서 메소드를 가져 오기 위해 채택되었지만 루비의 심볼은 변수를 나타내는 데 사용되지 않습니다.

문자열이 아닌 DataFrames에서 기호가 사용되는 이유는 DataFrames에서 열 값을 사용자 제공 식 내부의 변수에 바인딩하는 것이 일반적인 패턴이기 때문입니다. 따라서 기호는 변수를 데이터로 나타내는 데 사용하는 것이기 때문에 열 이름이 기호 인 것이 당연합니다. 현재 df[:foo]foo열에 액세스 하기 위해 작성 해야 하지만 나중에는 df.foo대신 열에 액세스 할 수 있습니다 . 이것이 가능 해지면 이름이 유효한 식별자 인 열만이 편리한 구문으로 액세스 할 수 있습니다.

또한보십시오:


6
인턴 : 컴퓨터 과학에서 문자열 인턴은 각각의 고유 한 문자열 값의 사본 하나만 저장하는 방법이며 변경 불가능합니다. 문자열을 문자열로 묶으면 문자열을 만들거나 묶을 때 더 많은 시간이 걸리면서 일부 문자열 처리 작업이 시간이나 공간 효율성이 향상됩니다. en.wikipedia.org/wiki/String_interning
xiaodai

어느 시점에서 당신은 쓰고 eval(:foo)또 다른 곳에 eval(sym). eval(:foo)와 사이에 의미있는 차이가 eval(foo)있습니까?
그레이 스케일

매우 그렇습니다 : eval(:foo)변수 foo가 바인딩 된 값을 제공 하는 반면 eval(foo)해당 값에 대해 eval을 호출합니다. 쓰기는 eval(:foo)단지에 해당 foo하므로 (글로벌 범위) eval(foo)과 같다 eval(eval(:foo)).
StefanKarpinski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.