Entonces, ¿por qué los creadores de Ruby tuvieron que usar el concepto symbolsen el lenguaje?
Bueno, ellos estrictamente "no tenían que", decidieron hacerlo. Además, tenga en cuenta que estrictamente hablando Symbols no son parte del lenguaje, son parte de la biblioteca central. Ellos no tienen una sintaxis literal de nivel de idioma, sino que funcionarían igual de bien si había que construir con ellos llamando Symbol::new.
Pregunto desde la perspectiva de un programador que no sea ruby tratando de entenderlo. Aprendí muchos otros idiomas y no encontré en ninguno de ellos la necesidad de especificar si estaba tratando o no con lo que Ruby llama symbols.
No dijiste cuáles son esos "muchos otros idiomas", pero aquí hay un pequeño extracto de idiomas que tienen un Symboltipo de datos como el de Ruby:
- ECMAScript , también JavaScript
- Scala
- Scheme , Common Lisp , Clojure (también, Clojure tiene palabras clave ), básicamente todos los idiomas de la familia Lisp, sus sucesores y primos las tienen
- Smalltalk , Newspeak y muchos otros idiomas de la familia Smalltalk (que probablemente es de donde Ruby los obtuvo), incluido Objective-C (aunque de forma limitada)
- Erlang (llamado átomos ) , también Elixir y LFE
- Julia
- Prolog (llamado átomos ), que probablemente es de donde Erlang los obtuvo
También hay otros lenguajes que proporcionan las características de Symbols en una forma diferente. En Java, por ejemplo, las características de Ruby's Stringse dividen en dos (en realidad tres) tipos: Stringy StringBuilder/ StringBuffer. Por otro lado, las características del Symboltipo de Ruby se pliegan en el Stringtipo de Java : los Strings de Java pueden ser internados , las cadenas literales y las Strings que son el resultado de expresiones constantes evaluadas en tiempo de compilación se internan automáticamente, los Strings generados dinámicamente se pueden internar llamando El String.internmétodo Un interno Stringen Java es exactamente como un Symbolen Ruby, pero no está implementado como un tipo separado, es solo un estado diferente que un JavaStringpuede estar en. (Nota: en versiones anteriores de Ruby, String#to_symsolía llamarse String#interny ese método todavía existe hoy en día como un alias heredado).
La pregunta principal podría ser: ¿ symbolsexiste el concepto de en Ruby como una intención de rendimiento sobre sí mismo y otros idiomas,
Symbols son ante todo un tipo de datos con semántica específica . Estas semánticas también permiten implementar algunas operaciones de rendimiento (por ejemplo, pruebas rápidas de igualdad O (1)), pero ese no es el objetivo principal.
o simplemente algo que se necesita para existir debido a la forma en que se escribe el idioma?
Symbols no son necesarios en absoluto en el lenguaje Ruby, Ruby funcionaría bien sin ellos. Son puramente una función de biblioteca. Hay exactamente un lugar en el lenguaje que está vinculado a Symbols: una defexpresión de definición de método se evalúa como Symboldenotando el nombre del método que se está definiendo. Sin embargo, ese es un cambio bastante reciente, antes de eso, el valor de retorno simplemente se dejó sin especificar. MRI simplemente evaluó a nil, Rubinius evaluó a un Rubinius::CompiledMethodobjeto, y así sucesivamente. También sería posible evaluar a un UnboundMethod... o simplemente a String.
¿Sería un programa en Ruby más ligero y / o más rápido que su, digamos, Python o Node homólogo? Si es así, ¿sería por symbols?
No estoy seguro de lo que estás preguntando aquí. El rendimiento es principalmente una cuestión de calidad de implementación, no de lenguaje. Además, Node ni siquiera es un lenguaje, es un marco de E / S creado para ECMAScript. Al ejecutar un script equivalente en IronPython y MRI, es probable que IronPython sea más rápido. Al ejecutar un script equivalente en CPython y JRuby + Truffle, es probable que JRuby + Truffle sea más rápido. Esto no tiene nada que ver con Symbols, sino con la calidad de la implementación: JRuby + Truffle tiene un compilador de optimización agresiva, además de toda la maquinaria de optimización de una JVM de alto rendimiento, CPython es un intérprete simple.
Dado que una de las intenciones de Ruby es ser fácil de leer y escribir para humanos, ¿no podrían sus creadores facilitar el proceso de codificación mediante la implementación de esas mejoras en el propio intérprete (como podría ser en otros idiomas)?
No. Symbols no son una optimización del compilador. Son un tipo de datos separado con una semántica específica. No son como los flonums de YARV , que son una optimización interna privada para Floats. La situación no es la misma que para Integer, Bignumy Fixnum, que debería ser un detalle de optimización interna privada invisible, pero desafortunadamente no lo es. (Esto finalmente va a ser fijado en Ruby 2.4, que elimina Fixnumy Bignumy las hojas sólo Integer.)
Hacerlo de la manera en que lo hace Java, ya que un estado especial de Strings normal significa que siempre debe ser cauteloso acerca de si sus Strings están en ese estado especial y bajo qué circunstancias están automáticamente en ese estado especial y cuándo no. Esa es una carga mucho más alta que simplemente tener un tipo de datos separado.
¿Habría una definición agnóstica del lenguaje de los símbolos y una razón para tenerlos en otros idiomas?
Symboles un tipo de datos que denota el concepto de nombre o etiqueta . SymbolLos s son objetos de valor , inmutables, generalmente inmediatos (si el lenguaje distingue tal cosa), sin estado y sin identidad. SymbolTambién se garantiza que dos s que son iguales son idénticos, en otras palabras, dos Symbols que son iguales son en realidad el mismo Symbol. Esto significa que la igualdad de valores y la igualdad de referencia son lo mismo, y por lo tanto, la igualdad es eficiente y O (1).
Los motivos para tenerlos en un idioma son realmente los mismos, independientemente del idioma. Algunos idiomas dependen más de ellos que otros.
En la familia Lisp, por ejemplo, no existe el concepto de "variable". En cambio, tiene Symbols asociados a valores.
En las lenguas con las capacidades de reflexión o introspección, Symbols se utilizan a menudo para referirse a los nombres de entidades reflejadas en el API de reflexión, por ejemplo, en Rubí, Object#methods, Object#singleton_methods, Object#public_methods, Object#protected_methods, y Object#public_methodsdevolver una Arrayde Symbols (aunque podrían igual de bien devolver una Arrayde Methods). Object#public_sendtoma un Symboldenotando el nombre del mensaje para enviarlo como argumento (aunque también acepta un String, Symboles más semánticamente correcto).
En ECMAScript, los Symbols son un componente fundamental para hacer que ECMAScript sea seguro en el futuro. También juegan un papel importante en la reflexión.