web-dev-qa-db-ja.com

ジュリアの「シンボル」とは何ですか?

具体的には、JuliaのDataFramesパッケージ、具体的にはnamesオプションを指定したreadtable()関数を使用しようとしていますが、これにはシンボルのベクトルが必要です。

  • シンボルとは何ですか?
  • なぜ彼らは文字列のベクトルよりもそれを選択するのですか?

これまでのところ、ジュリア語のWordシンボルへの参照はほんの一握りしかありませんでした。シンボルは「:var」で表されているように見えますが、それが何であるかははっきりしていません。

余談:走れる

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

私の2つの箇条書きの質問はまだ残っています。

103
Mageek

Juliaのシンボルは、LISP、Scheme、またはRubyと同じです。しかし、私の意見では 答え これらの関連する質問に対する 本当に満足のいくものではありません 。これらの答えを読むと、記号が文字列と異なる理由は、文字列は可変であるが、記号は不変であり、記号も「インターン」されているということです。文字列は、たまたまRubyとLISPで変更可能ですが、Juliaにはありません。その違いは実際にはニシンです。同等の比較を高速化するために-関係のない実装の詳細であり、シンボルをインターンせず、言語がまったく同じである実装を作成できます。

それでは、本当にシンボルとは何ですか?その答えは、ジュリアとLISPの共通点にあります。つまり、言語自体のデータ構造として言語のコードを表現する能力です。これを "homoiconicity"Wikipedia )と呼ぶ人もいますが、他の人は言語が同音異義語であるためにはそれだけで十分だとは思わないようです。しかし、用語は実際には重要ではありません。ポイントは、言語が独自のコードを表現できる場合、割り当て、関数呼び出し、リテラル値として記述できるものなどを表現する方法が必要であるということです。独自の変数を表現する方法も必要です。つまり、次のように表現する方法が必要です-データとして-この左側の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"。次に、変数symに格納されているシンボル:fooを使用して式を作成する別の例を示します。

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"にバインドされているときにこれを行おうとすると、動作しません。

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""

これがなぜ機能しないのかは明らかです。pretty手動で"foo" = "bar"を割り当てようとしても、機能しません。

これがシンボルの本質です。シンボルは、メタプログラミングで変数を表すために使用されます。データ型としてシンボルを取得したら、もちろん、ハッシュキーなどの他の目的に使用するのは魅力的です。しかし、それは別の主な目的を持つデータ型の偶発的で日和見的な使用法です。

Rubyしばらく前に話をやめたことに注意してください。これはRubyがホモイコニックではないためです。Rubyはその表現をRubyオブジェクト。したがって、Rubyのシンボルタイプは、痕跡器官の一種です。LISPから継承されたが、元の目的には使用されなくなった残りの適応。Rubyシンボルは、メソッドテーブルからメソッドを引き出すためにハッシュキーとして他の目的を選択しました。ただし、Rubyの記号は変数の表現には使用されません。

文字列ではなくシンボルがDataFrameで使用される理由については、列の値をユーザー指定の式内の変数にバインドするのがDataFrameの一般的なパターンだからです。したがって、シンボルは変数をデータとして表すために使用するものとまったく同じであるため、列名がシンボルであるのは自然なことです。現在、foo列にアクセスするにはdf[:foo]を記述する必要がありますが、将来はdf.fooとしてアクセスできるようになる可能性があります。それが可能になると、名前が有効な識別子である列のみがこの便利な構文でアクセス可能になります。

以下も参照してください:

187
StefanKarpinski