Alors, pourquoi les créateurs de Ruby ont-ils dû utiliser le concept de symbolsdans le langage?
Eh bien, ils n'ont pas strictement «dû», ils ont choisi de le faire. Notez également que les Symbols à 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 Symboltype 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 Symbols sous une forme différente. En Java, par exemple, les fonctionnalités de Ruby Stringsont divisées en deux (en fait trois) types: Stringet StringBuilder/ StringBuffer. D'un autre côté, les fonctionnalités du Symboltype Ruby sont repliées dans le Stringtype Java : les Java Strings peuvent être internés , les chaînes littérales et les Strings qui sont le résultat d'expressions constantes évaluées au moment de la compilation sont automatiquement internées, les Strings générés dynamiquement peuvent être internés en appelant la String.internméthode. Un interné Stringen Java est exactement comme un SymbolRuby, mais il n'est pas implémenté comme un type séparé, c'est juste un état différent qu'un JavaStringpeut être dans. (Remarque: dans les versions antérieures de Ruby, elle String#to_symétait appelée String#internet cette méthode existe encore aujourd'hui en tant qu'alias hérité.)
La question principale pourrait être: le concept de symbolsRuby existe-t-il comme une intention de performance sur lui-même et sur d'autres langages,
Symbols 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?
Symbols 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é à Symbols: une defexpression de définition de méthode s'évalue en Symbolindiquant 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::CompiledMethodobjet, 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 Symbols 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 ° Symbolne 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, Bignumet Fixnumqui 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 Fixnumet Bignumet feuilles seulement Integer.)
Le faire comme Java le fait, en tant qu'état spécial de Strings normal signifie que vous devez toujours vous méfier de savoir si vos Strings 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?
Symbolest un type de données qui désigne le concept de nom ou d' étiquette . Symbols 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 Symbols qui sont égaux sont également garantis identiques, en d'autres termes, deux Symbols 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 Symbols associés aux valeurs.
Dans les langues avec des capacités de réflexion ou introspectives, Symbols 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_methodset Object#public_methodsretourner un Arrayde Symbols (bien qu'ils pourraient tout aussi bien retourner un Arrayde Methods). Object#public_sendprend un Symboldénotant le nom du message à envoyer comme argument (bien qu'il accepte également un Stringaussi, Symbolest plus sémantiquement correct).
Dans ECMAScript, les Symbols sont un élément fondamental pour rendre ECMAScript plus sûr à l'avenir. Ils jouent également un grand rôle dans la réflexion.