Entonces, ¿por qué los creadores de Ruby tuvieron que usar el concepto symbols
en el lenguaje?
Bueno, ellos estrictamente "no tenían que", decidieron hacerlo. Además, tenga en cuenta que estrictamente hablando Symbol
s 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 Symbol
tipo 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 Symbol
s en una forma diferente. En Java, por ejemplo, las características de Ruby's String
se dividen en dos (en realidad tres) tipos: String
y StringBuilder
/ StringBuffer
. Por otro lado, las características del Symbol
tipo de Ruby se pliegan en el String
tipo de Java : los String
s de Java pueden ser internados , las cadenas literales y las String
s que son el resultado de expresiones constantes evaluadas en tiempo de compilación se internan automáticamente, los String
s generados dinámicamente se pueden internar llamando El String.intern
método Un interno String
en Java es exactamente como un Symbol
en Ruby, pero no está implementado como un tipo separado, es solo un estado diferente que un JavaString
puede estar en. (Nota: en versiones anteriores de Ruby, String#to_sym
solía llamarse String#intern
y ese método todavía existe hoy en día como un alias heredado).
La pregunta principal podría ser: ¿ symbols
existe el concepto de en Ruby como una intención de rendimiento sobre sí mismo y otros idiomas,
Symbol
s 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?
Symbol
s 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 Symbol
s: una def
expresión de definición de método se evalúa como Symbol
denotando 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::CompiledMethod
objeto, 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 Symbol
s, 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. Symbol
s 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 Float
s. La situación no es la misma que para Integer
, Bignum
y 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 Fixnum
y Bignum
y las hojas sólo Integer
.)
Hacerlo de la manera en que lo hace Java, ya que un estado especial de String
s normal significa que siempre debe ser cauteloso acerca de si sus String
s 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?
Symbol
es un tipo de datos que denota el concepto de nombre o etiqueta . Symbol
Los s son objetos de valor , inmutables, generalmente inmediatos (si el lenguaje distingue tal cosa), sin estado y sin identidad. Symbol
También se garantiza que dos s que son iguales son idénticos, en otras palabras, dos Symbol
s 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 Symbol
s asociados a valores.
En las lenguas con las capacidades de reflexión o introspección, Symbol
s 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_methods
devolver una Array
de Symbol
s (aunque podrían igual de bien devolver una Array
de Method
s). Object#public_send
toma un Symbol
denotando el nombre del mensaje para enviarlo como argumento (aunque también acepta un String
, Symbol
es más semánticamente correcto).
En ECMAScript, los Symbol
s son un componente fundamental para hacer que ECMAScript sea seguro en el futuro. También juegan un papel importante en la reflexión.