Alors, pourquoi les créateurs de Ruby ont-ils dû utiliser le concept de symbols
dans le langage?
Eh bien, ils n'ont pas strictement «dû», ils ont choisi de le faire. Notez également que les Symbol
s à proprement parler ne font pas partie du langage, ils font partie de la bibliothèque principale. Ils n'ont une syntaxe littérale du niveau de la langue, mais ils travailleraient aussi bien si vous deviez les construire en appelant .Symbol::new
Je demande du point de vue d'un programmeur non rubis essayant de le comprendre. J'ai appris beaucoup d'autres langues et je n'ai trouvé dans aucune d'entre elles la nécessité de spécifier si j'avais affaire ou non à ce que Ruby appelle symbols
.
Vous n'avez pas dit ce que sont ces "beaucoup d'autres langues", mais voici juste un petit extrait de langues qui ont un Symbol
type de données comme Ruby:
- ECMAScript , également JavaScript
- Scala
- Scheme , Common Lisp , Clojure (aussi, Clojure a des mots-clés ), essentiellement toutes les langues de la famille Lisp, ses successeurs et cousins les ont
- Smalltalk , Newspeak et de nombreux autres langages de la famille Smalltalk (qui est probablement d'où Ruby les a obtenus), y compris Objective-C (bien que sous une forme limitée)
- Erlang (appelé atomes ) , également Elixir et LFE
- Julia
- Prolog (appelés atomes ), qui est probablement d'où Erlang les a obtenus
Il existe également d'autres langages qui fournissent les fonctionnalités de Symbol
s sous une forme différente. En Java, par exemple, les fonctionnalités de Ruby String
sont divisées en deux (en fait trois) types: String
et StringBuilder
/ StringBuffer
. D'un autre côté, les fonctionnalités du Symbol
type Ruby sont repliées dans le String
type Java : les Java String
s peuvent être internés , les chaînes littérales et les String
s qui sont le résultat d'expressions constantes évaluées au moment de la compilation sont automatiquement internées, les String
s générés dynamiquement peuvent être internés en appelant la String.intern
méthode. Un interné String
en Java est exactement comme un Symbol
Ruby, mais il n'est pas implémenté comme un type séparé, c'est juste un état différent qu'un JavaString
peut être dans. (Remarque: dans les versions antérieures de Ruby, elle String#to_sym
était appelée String#intern
et cette méthode existe encore aujourd'hui en tant qu'alias hérité.)
La question principale pourrait être: le concept de symbols
Ruby existe-t-il comme une intention de performance sur lui-même et sur d'autres langages,
Symbol
s sont avant tout un type de données avec une sémantique spécifique . Ces sémantiques permettent également d'implémenter certaines opérations performantes (par exemple le test d'égalité rapide O (1)), mais ce n'est pas le but principal.
ou simplement quelque chose qui doit exister en raison de la façon dont la langue est écrite?
Symbol
s ne sont pas du tout nécessaires dans le langage Ruby, Ruby fonctionnerait très bien sans eux. Ils sont purement une fonctionnalité de bibliothèque. Il y a exactement un endroit dans le langage qui est lié à Symbol
s: une def
expression de définition de méthode s'évalue en Symbol
indiquant le nom de la méthode en cours de définition. Cependant, c'est un changement assez récent, avant cela, la valeur de retour était simplement laissée non spécifiée. L'IRM simplement évaluée à nil
, Rubinius évaluée à un Rubinius::CompiledMethod
objet, et ainsi de suite. Il serait également possible d'évaluer un UnboundMethod
… ou juste un String
.
Un programme dans Ruby serait-il plus léger et / ou plus rapide que son homologue, disons Python ou Node? Si oui, serait-ce à cause de cela symbols
?
Je ne suis pas sûr de ce que vous demandez ici. Les performances sont principalement une question de qualité de mise en œuvre, pas de langue. De plus, Node n'est même pas un langage, c'est un cadre d'E / S à événements pour ECMAScript. En exécutant un script équivalent sur IronPython et MRI, IronPython est susceptible d'être plus rapide. Exécuter un script équivalent sur CPython et JRuby + Truffle, JRuby + Truffle est susceptible d'être plus rapide. Cela n'a rien à voir avec Symbol
s mais avec la qualité de l'implémentation: JRuby + Truffle a un compilateur optimisant de manière agressive, ainsi que toute la machinerie d'optimisation d'une machine virtuelle Java haute performance, CPython est un simple interprète.
Étant donné que l'une des intentions de Ruby est d'être facile à lire et à écrire pour les humains, ses créateurs ne pourraient-ils pas faciliter le processus de codage en mettant en œuvre ces améliorations dans l'interpréteur lui-même (comme cela pourrait être dans d'autres langues)?
Les n ° Symbol
ne sont pas une optimisation du compilateur. Il s'agit d'un type de données distinct avec une sémantique spécifique. Ils ne sont pas comme les flonums de YARV , qui sont une optimisation interne privée pour l' alFloat
. La situation est la même que pour Integer
, Bignum
et Fixnum
qui devrait être un détail d'optimisation interne privée invisible, mais est malheureusement pas. (Ce va enfin être fixé dans Ruby 2.4, qui enlève Fixnum
et Bignum
et feuilles seulement Integer
.)
Le faire comme Java le fait, en tant qu'état spécial de String
s normal signifie que vous devez toujours vous méfier de savoir si vos String
s sont dans cet état spécial et dans quelles circonstances ils sont automatiquement dans cet état spécial et quand ce n'est pas le cas. C'est une charge beaucoup plus élevée que d'avoir simplement un type de données séparé.
Y aurait-il une définition indépendante de la langue des symboles et une raison de les avoir dans d'autres langues?
Symbol
est un type de données qui désigne le concept de nom ou d' étiquette . Symbol
s sont des objets de valeur , immuables, généralement immédiats (si le langage distingue une telle chose), apatrides, et n'ont pas d'identité. Deux Symbol
s qui sont égaux sont également garantis identiques, en d'autres termes, deux Symbol
s qui sont égaux sont en fait les mêmes Symbol
. Cela signifie que l'égalité de valeur et l'égalité de référence sont la même chose, et donc l'égalité est efficace et O (1).
Les raisons de les avoir dans une langue sont vraiment les mêmes, indépendamment de la langue. Certaines langues en dépendent plus que d'autres.
Dans la famille Lisp, par exemple, il n'y a pas de concept de "variable". Au lieu de cela, vous avez des Symbol
s associés aux valeurs.
Dans les langues avec des capacités de réflexion ou introspectives, Symbol
s sont souvent utilisés pour désigner les noms des entités reflétées dans les API de réflexion, par exemple dans Ruby, Object#methods
, Object#singleton_methods
, Object#public_methods
, Object#protected_methods
et Object#public_methods
retourner un Array
de Symbol
s (bien qu'ils pourraient tout aussi bien retourner un Array
de Method
s). Object#public_send
prend un Symbol
dénotant le nom du message à envoyer comme argument (bien qu'il accepte également un String
aussi, Symbol
est plus sémantiquement correct).
Dans ECMAScript, les Symbol
s sont un élément fondamental pour rendre ECMAScript plus sûr à l'avenir. Ils jouent également un grand rôle dans la réflexion.