Quindi, perché i creatori di Ruby hanno dovuto usare il concetto di symbols
nella lingua?
Bene, non hanno "dovuto" rigorosamente, hanno scelto di. Inoltre, si noti che i termini rigorosamente Symbol
non fanno parte della lingua, fanno parte della libreria principale. Essi non hanno la sintassi letterale-livello di linguaggio, ma avrebbe funzionato altrettanto bene se si doveva costruirli chiamando Symbol::new
.
Chiedo dal punto di vista di un programmatore non rubino che cerca di capirlo. Ho imparato molte altre lingue e in nessuna di esse ho trovato la necessità di specificare se avevo a che fare con ciò che Ruby chiama symbols
.
Non hai detto cosa sono quelle "molte altre lingue", ma ecco solo un piccolo estratto di lingue che hanno un Symbol
tipo di dati come Ruby:
Esistono anche altre lingue che forniscono le caratteristiche di Symbol
s in una forma diversa. In Java, ad esempio, le caratteristiche di Ruby String
sono divise in due (in realtà tre) tipi: String
e StringBuilder
/ StringBuffer
. D'altra parte, le caratteristiche del Symbol
tipo di Ruby sono piegate nel String
tipo Java : Java String
s può essere internato , stringhe letterali e String
s che sono il risultato di espressioni costanti valutate in fase di compilazione vengono automaticamente internate, le String
s generate dinamicamente possono essere internate chiamando il String.intern
metodo. Un internato String
in Java è esattamente come Symbol
in Ruby, ma non è implementato come un tipo separato, è solo uno stato diverso rispetto a un JavaString
può essere in. (Nota: nelle versioni precedenti di Ruby, String#to_sym
veniva chiamato String#intern
e quel metodo esiste ancora oggi come alias legacy.)
La domanda principale potrebbe essere: il concetto di symbols
in Ruby esiste come intento performativo su se stesso e su altre lingue,
Symbol
s sono innanzitutto un tipo di dati con semantica specifica . Queste semantiche consentono anche di implementare alcune operazioni performanti (ad es. Test rapido sull'uguaglianza O (1)), ma non è questo lo scopo principale.
o semplicemente qualcosa che è necessario per esistere a causa del modo in cui è scritta la lingua?
Symbol
s non sono affatto necessari nella lingua Ruby, Ruby funzionerebbe perfettamente senza di loro. Sono puramente una funzione di libreria. Esiste esattamente un posto nel linguaggio che è legato a Symbol
s: def
un'espressione di definizione del metodo Symbol
restituisce una denotazione del nome del metodo che viene definito. Tuttavia, si tratta di una modifica piuttosto recente, prima che il valore restituito fosse semplicemente lasciato non specificato. La risonanza magnetica è stata semplicemente valutata nil
, Rubinio ha valutato un Rubinius::CompiledMethod
oggetto e così via. Sarebbe anche possibile valutare un UnboundMethod
... o solo un String
.
Un programma in Ruby sarebbe più leggero e / o più veloce della sua, diciamo, controparte Python o Node? Se è così, sarebbe a causa di symbols
?
Non sono sicuro di quello che stai chiedendo qui. Le prestazioni dipendono principalmente dalla qualità dell'implementazione, non dal linguaggio. Inoltre, Node non è nemmeno una lingua, è un framework I / O per ECMAScript. Eseguendo uno script equivalente su IronPython e MRI, è probabile che IronPython sia più veloce. Eseguendo uno script equivalente su CPython e JRuby + Truffle, è probabile che JRuby + Truffle sia più veloce. Questo non ha nulla a che fare con Symbol
s ma con la qualità dell'implementazione: JRuby + Truffle ha un compilatore che ottimizza in modo aggressivo, oltre a tutta la macchina di ottimizzazione di una JVM ad alte prestazioni, CPython è un semplice interprete.
Poiché uno degli intenti di Ruby è di essere facile da leggere e scrivere per gli umani, i suoi creatori non potrebbero facilitare il processo di codifica implementando quei miglioramenti nell'interprete stesso (come potrebbe essere in altre lingue)?
No. Symbol
s non sono un'ottimizzazione del compilatore. Sono un tipo di dati separato con semantica specifica. Non sono come i flonum di YARV , che sono un'ottimizzazione interna privata per Float
s. La situazione non è la stessa di Integer
, Bignum
e Fixnum
, che dovrebbe essere un dettaglio di ottimizzazione interno privato invisibile, ma sfortunatamente non lo è. (Questo è finalmente sta per essere fissato in Ruby 2.4, che rimuove Fixnum
e Bignum
foglie e solo Integer
.)
Farlo nel modo in cui lo fa Java, in quanto uno stato speciale di normali String
significa che devi sempre stare attento al fatto che i tuoi siano o meno String
in quello stato speciale e in quali circostanze si trovino automaticamente in quello stato speciale e quando no. Questo è un onere molto più elevato rispetto al semplice avere un tipo di dati separato.
Ci sarebbe una definizione agnostica dei simboli e un motivo per averli in altre lingue?
Symbol
è un tipo di dati che indica il concetto di nome o etichetta . Symbol
sono oggetti di valore , immutabili, di solito immediati (se il linguaggio distingue una cosa del genere), apolidi e non hanno identità. Due Symbol
s che sono uguali sono ugualmente garantiti, in altre parole, due Symbol
s che sono uguali sono effettivamente gli stessi Symbol
. Ciò significa che l'uguaglianza di valore e l'uguaglianza di riferimento sono la stessa cosa, e quindi l'uguaglianza è efficiente e O (1).
I motivi per averli in una lingua sono davvero gli stessi, indipendentemente dalla lingua. Alcune lingue dipendono più da esse di altre.
Nella famiglia Lisp, ad esempio, non esiste un concetto di "variabile". Invece, hai Symbol
s associato ai valori.
In lingue con capacità riflettenti o introspettive, Symbol
s sono spesso utilizzati per indicare i nomi delle entità riflesse nelle API di riflessione, ad esempio in Ruby, Object#methods
, Object#singleton_methods
, Object#public_methods
, Object#protected_methods
, e Object#public_methods
restituire un Array
di Symbol
s (anche se potrebbero altrettanto bene restituire un Array
di Method
s). Object#public_send
prende un Symbol
denotando il nome del messaggio da inviare come argomento (anche se accetta anche un String
, Symbol
è più semanticamente corretto).
In ECMAScript, gli Symbol
s sono un elemento fondamentale per rendere ECMAScript sicuro in futuro. Inoltre svolgono un ruolo importante nella riflessione.