Julia'daki semboller Lisp, Scheme veya Ruby'deki ile aynıdır. Bununla birlikte, ilgili soruların cevapları bence pek tatmin edici değil . Bu cevapları okursanız, bir sembolün bir dizeden farklı olmasının nedeni, dizelerin değişebilirken sembollerin değişmez olması ve sembollerin de "iç içe geçmiş" olmasıdır - bu ne anlama geliyorsa. Dizeler Ruby ve Lisp'te değiştirilebilir, ancak Julia'da değiller ve bu fark aslında bir kırmızı ringa balığı. Sembollerin iç içe geçmesi - yani hızlı eşitlik karşılaştırmaları için dil uygulaması tarafından karma hale getirilmesi - aynı zamanda alakasız bir uygulama ayrıntısıdır. İç semboller içermeyen bir uygulamaya sahip olabilirsiniz ve dil tamamen aynı olacaktır.
Peki sembol nedir, gerçekten? Cevap Julia ve Lisp'in ortak bir noktasında yatıyor - dilin kodunu dilin kendisinde bir veri yapısı olarak gösterme yeteneği. Bazı insanlar buna "homoikoniklik" ( Wikipedia ) diyorlar , ancak diğerleri, bir dilin homoikonik olması için tek başına yeterli olduğunu düşünmüyor. Ancak terminoloji gerçekten önemli değil. Mesele şu ki, bir dil kendi kodunu temsil edebildiğinde, atamalar, işlev çağrıları, değişmez değerler olarak yazılabilen şeyler gibi şeyleri temsil etmek için bir yola ihtiyaç duyar. Ayrıca kendi değişkenlerini temsil etmenin bir yoluna ihtiyaç duyar. Yani, foo
bunun sol tarafındaki verileri - veri olarak - temsil etmenin bir yoluna ihtiyacınız var :
foo == "foo"
Şimdi konunun özüne geliyoruz: bir sembol ile bir dizi arasındaki fark foo
, bu karşılaştırmanın sol tarafı ile "foo"
sağ taraf arasındaki farktır . Solda foo
bir tanımlayıcı var ve foo
geçerli kapsamdaki değişkene bağlı değeri değerlendiriyor . Sağda, "foo"
bir dize değişmezidir ve "foo" dize değeri olarak değerlendirilir. Hem Lisp hem de Julia'daki bir sembol, bir değişkeni veri olarak nasıl temsil ettiğinizdir. Bir dize sadece kendini temsil eder. eval
Onlara uygulayarak farkı görebilirsiniz :
julia> eval(:foo)
ERROR: foo not defined
julia> foo = "hello"
"hello"
julia> eval(:foo)
"hello"
julia> eval("foo")
"foo"
Sembolün neyi :foo
değerlendireceği, değişkenin foo
bağlı olduğu şeye bağlıdır - eğer varsa - , oysa "foo"
her zaman sadece "foo" olarak değerlendirilir. Julia'da değişkenler kullanan ifadeler oluşturmak istiyorsanız, o zaman semboller kullanıyorsunuz (bilseniz de bilmeseniz de). Örneğin:
julia> ex = :(foo = "bar")
:(foo = "bar")
julia> dump(ex)
Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol foo
2: String "bar"
typ: Any
Dışarı atılan şey, diğer şeylerin yanı sıra :foo
, kodu alıntı yaparak elde ettiğiniz ifade nesnesinin içinde bir sembol nesnesi olduğunu gösterir foo = "bar"
. İşte :foo
değişkende depolanan sembolle bir ifade oluşturan başka bir örnek 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"
Bunu sym
dizeye bağlıyken yapmaya çalışırsanız "foo"
, işe yaramaz:
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""
Bunun neden işe yaramayacağını görmek oldukça açık - "foo" = "bar"
elle atamayı denediyseniz , işe yaramayacak.
Bu, bir sembolün özüdür: Bir sembol, meta programlamada bir değişkeni temsil etmek için kullanılır. Veri türü olarak sembollere sahip olduğunuzda, elbette, bunları karma anahtarlar gibi başka şeyler için kullanmak cazip hale gelir. Ancak bu, başka bir birincil amacı olan bir veri türünün tesadüfi, fırsatçı bir kullanımıdır.
Bir süre önce Ruby hakkında konuşmayı bıraktığımı unutmayın. Bunun nedeni, Ruby'nin homoiconic olmamasıdır: Ruby, ifadelerini Ruby nesneleri olarak temsil etmez. Yani Ruby'nin sembol türü, bir tür körelmiş organdır - Lisp'ten miras kalan, ancak artık orijinal amacı için kullanılmayan artık bir uyarlama. Ruby sembolleri, metot tablolarından metotları çıkarmak için hash anahtarları olarak başka amaçlar için birlikte seçilmiştir, ancak Ruby'deki semboller değişkenleri temsil etmek için kullanılmaz.
Sembollerin neden dizeler yerine DataFrames'te kullanıldığına gelince, bunun nedeni DataFrames'te sütun değerlerini kullanıcı tarafından sağlanan ifadelerin içindeki değişkenlere bağlamak için yaygın bir model olmasıdır. Bu nedenle sütun adlarının sembol olması doğaldır, çünkü semboller tam olarak değişkenleri veri olarak temsil etmek için kullandığınız şeydir. Şu anda, sütuna df[:foo]
erişmek için yazmak zorundasınız foo
, ancak gelecekte df.foo
bunun yerine ona erişmeniz mümkün olabilir . Bu mümkün olduğunda, yalnızca adları geçerli tanımlayıcılar olan sütunlara bu uygun sözdizimi ile erişilebilir.
Ayrıca bakınız: