Qu'est ce qu'un "symbole" de Julia?

spécifiquement: J'essaie d'utiliser le paquet DataFrames de Julia, en particulier la fonction readtable() avec l'option names, mais cela nécessite un vecteur de symboles.

  • qu'est ce qu'un symbole?
  • pourquoi choisiraient-ils ça plutôt qu'un vecteur de cordes?

jusqu'à présent, je n'ai trouvé qu'une poignée de références au symbole du mot dans la langue Julia. Il semble que les symboles sont représentés par": var", mais il est loin d'être clair pour moi ce qu'ils sont.

mis à part: Je peux lancer

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

mes deux questions sont toujours valables.

82
demandé sur Mageek 2014-05-05 23:58:17

1 réponses

les symboles de Julia sont les mêmes que dans Lisp, Scheme ou Ruby. Toutefois, les réponses à ces questions connexes ne sont pas vraiment satisfaisantes , à mon avis. Si vous lisez ces réponses, il semble que la raison pour laquelle un symbole est différent d'une chaîne est que les chaînes sont mutables tandis que les symboles sont immuables, et les symboles sont également "internés" – quoi que cela signifie. Les cordes sont muables en Ruby et en Lisp, mais pas en Julia., et cette différence est en fait un leurre. Le fait que les symboles soient internés – c. – à-d. hachurés par la mise en œuvre de la langue pour des comparaisons rapides de l'égalité-est également un détail de mise en œuvre non pertinent. Vous pourriez avoir une implémentation qui ne fait pas de symboles intern et le langage serait exactement le même.

Alors, qu'est ce qu'un symbole, vraiment? La réponse se trouve dans quelque chose que Julia et Lisp ont en commun – la capacité de représenter le code de la langue comme une structure de données dans le langage lui-même. Certains appellent cela " homoiconicité " ( Wikipedia ), mais d'autres ne semblent pas penser que seul est suffisant pour qu'une langue soit homoiconique. Mais la terminologie n'a pas vraiment d'importance. Le fait est que lorsqu'une langue peut représenter son propre code, elle a besoin d'une façon de représenter des choses comme des tâches, des appels de fonction, des choses qui peuvent être écrites comme des valeurs littérales, etc. Il lui faut aussi un moyen de représenter ses propres variables. C'est-à-dire: vous avez besoin d'une façon de représenter-en tant que données – le foo sur le côté gauche de ceci:

foo == "foo"

nous arrivons maintenant au cœur de la question: la différence entre un symbole et une corde est la différence entre foo du côté gauche de cette comparaison et "foo" du côté droit. Sur la gauche, foo est un identificateur et il correspond à la valeur liée à la variable foo dans le champ d'application actuel. Sur la droite, "foo" est une chaîne de caractères littérale qui est évaluée à la valeur"foo". Un symbole dans Lisp et Julia est la façon dont vous représentez une variable en tant que donnée. Une chaîne représente lui-même. Vous pouvez voir la différence en leur appliquant eval :

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

julia> foo = "hello"
"hello"

julia> eval(:foo)
"hello"

julia> eval("foo")
"foo"

ce que le symbole :foo évalue dépend de quoi – s'il y a quelque chose-la variable foo est liée, tandis que "foo" évalue toujours juste à "foo". Si vous voulez construire des expressions dans Julia qui utilisent des variables, alors vous utilisez des symboles (que vous le sachiez ou non). Par exemple:

julia> ex = :(foo = "bar")
:(foo = "bar")

julia> dump(ex)
Expr
  head: Symbol =
  args: Array{Any}((2,))
    1: Symbol foo
    2: String "bar"
  typ: Any

ce que cela montre, entre autres choses, c'est qu'il y a un objet symbole :foo à l'intérieur de l'objet expression que vous obtenez en citant le code foo = "bar" . Voici un autre exemple, la construction d'une expression avec le symbole :foo stocké dans la 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"

Si vous essayez de faites ceci quand sym est lié à la chaîne "foo" , ça ne marchera pas:

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

il est assez clair de voir pourquoi cela ne marchera pas – si vous avez essayé d'assigner "foo" = "bar" à la main, il ne fonctionnera pas non plus.

c'est l'essence d'un symbole: un symbole est utilisé pour représenter une variable en métaprogrammation. Une fois que vous avez des symboles comme un type de données, bien sûr, il devient tentant de les utiliser pour d'autres choses, comme clés de hachage. Mais c'est une utilisation fortuite et opportuniste d'un type de données ayant un autre but premier.

notez que J'ai arrêté de parler de Ruby il y a un moment. C'est parce que Ruby n'est pas homoiconique: Ruby ne représente pas ses expressions comme des objets Ruby. Donc le type de symbole de Ruby est une sorte d'organe vestigial – une adaptation restante, héritée de Lisp, mais n'est plus utilisé pour son but original. Les symboles Ruby ont été cooptés à d'autres fins – comme des clés de hachage, pour extraire les méthodes de la méthode tables-mais les symboles dans Ruby ne sont pas utilisés pour représenter des variables.

quant à savoir pourquoi les symboles sont utilisés dans les images de données plutôt que dans les chaînes de caractères, c'est parce que c'est un motif courant dans les images de données pour lier les valeurs de colonne aux variables à l'intérieur des expressions fournies par l'utilisateur. Il est donc naturel que les noms de colonnes soient des symboles, puisque les symboles sont exactement ce que vous utilisez pour représenter des variables en tant que données. Actuellement, vous devez écrire df[:foo] pour accéder à la colonne foo , mais dans le futur, vous pouvez être en mesure d'y accéder par df.foo à la place. Lorsque cela sera possible, seules les colonnes dont les noms sont des identificateurs valides seront accessibles avec cette syntaxe commode.

Voir aussi:

148
répondu StefanKarpinski 2017-09-23 20:19:47