Então, por que os criadores de Ruby tiveram que usar o conceito de symbolsna linguagem?
Bem, eles não precisavam "estritamente", eles escolheram. Além disso, observe que, estritamente falando, Symbols não fazem parte do idioma, eles fazem parte da biblioteca principal. Eles possuem sintaxe literal no nível do idioma, mas funcionariam da mesma forma se você tivesse que construí-los chamando Symbol::new.
Eu pergunto da perspectiva de um programador não-rubi tentando entender isso. Eu aprendi muitas outras línguas e não encontrei em nenhuma delas a necessidade de especificar se eu estava lidando ou não com o que Ruby chama symbols.
Você não disse o que são essas "muitas outras línguas", mas aqui está apenas um pequeno trecho de linguagem que possui um Symboltipo de dados como o Ruby:
- ECMAScript , também JavaScript
- Scala
- Scheme , Common Lisp , Clojure (também, Clojure tem palavras - chave ), basicamente todos os idiomas da família Lisp, seus sucessores e primos os têm
- Smalltalk , Newspeak e muitos outros idiomas da família Smalltalk (que provavelmente é de onde o Ruby os obteve), incluindo o Objective-C (embora de forma limitada)
- Erlang (chamados átomos ) , também Elixir e LFE
- Julia
- Prolog (chamados átomos ), o que provavelmente é de onde Erlang os obteve
Existem também outros idiomas que fornecem os recursos de Symbols de uma forma diferente. Em Java, por exemplo, os recursos de Ruby Strings são divididos em dois (na verdade três) tipos: Stringe StringBuilder/ StringBuffer. Por outro lado, as características de Ruby Symboltipo são dobradas para o Java StringTipo: Java Strings podem ser internado , strings literais e Strings que são o resultado de tempo de compilação expressões constantes avaliadas são automaticamente internado, geradas dinamicamente Strings podem ser internado chamando o String.internmétodo Um internado Stringem Java é exatamente como um Symbolem Ruby, mas não é implementado como um tipo separado, é apenas um estado diferente do que um JavaStringpode estar disponível. (Nota: nas versões anteriores do Ruby, String#to_symcostumava ser chamado String#interne esse método ainda existe hoje como um alias herdado.)
A principal questão poderia ser: o conceito de symbolsRuby existe como uma intenção de desempenho sobre si e outras linguagens,
Symbols são antes de tudo um tipo de dados com semântica específica . Essa semântica também possibilita implementar algumas operações de alto desempenho (por exemplo, testes rápidos de igualdade O (1)), mas esse não é o objetivo principal.
ou apenas algo que é necessário para existir devido à maneira como a linguagem é escrita?
Symbols não são necessários na linguagem Ruby, o Ruby funcionaria perfeitamente sem eles. Eles são puramente um recurso de biblioteca. Há exatamente um lugar no idioma vinculado a Symbols: uma defexpressão de definição de método é avaliada como Symboldenotando o nome do método que está sendo definido. No entanto, essa é uma alteração bastante recente, antes disso, o valor de retorno simplesmente não foi especificado. A RM simplesmente avaliou nil, Rubinius avaliou um Rubinius::CompiledMethodobjeto e assim por diante. Também seria possível avaliar para um UnboundMethod... ou apenas um String.
Um programa em Ruby seria mais leve e / ou mais rápido que seu, digamos, equivalente em Python ou Node? Se sim, seria por causa disso symbols?
Não tenho certeza do que você está perguntando aqui. O desempenho é principalmente uma questão de qualidade de implementação, não de linguagem. Além disso, o Node nem sequer é uma linguagem, é uma estrutura de E / S registrada para ECMAScript. Executando um script equivalente no IronPython e MRI, o IronPython provavelmente será mais rápido. Executando um script equivalente no CPython e JRuby + Truffle, é provável que o JRuby + Truffle seja mais rápido. Isso não tem nada a ver com Symbols, mas com a qualidade da implementação: o JRuby + Truffle possui um compilador de otimização agressiva, além de todo o mecanismo de otimização de uma JVM de alto desempenho, o CPython é um intérprete simples.
Como uma das intenções de Ruby é ser fácil de ler e escrever para humanos, seus criadores não poderiam facilitar o processo de codificação implementando essas melhorias no próprio intérprete (como pode ser em outros idiomas)?
No. Symbols não são uma otimização de compilador. Eles são um tipo de dados separado com semântica específica. Eles não são como os flonums do YARV , que são uma otimização interna privada para Floats. A situação não é a mesma que para Integer, Bignume Fixnum, o que deve ser um detalhe otimização interna privada invisível, mas infelizmente não é. (Isto é, finalmente, vai ser fixado em Ruby 2.4, que remove Fixnume Bignume folhas apenas Integer.)
Fazer isso da maneira que o Java faz, como um estado especial de Strings normal, significa que você sempre precisa ser cauteloso sobre se seus Strings estão ou não nesse estado especial e sob quais circunstâncias eles estão automaticamente nesse estado especial e quando não. Esse é um fardo muito maior do que simplesmente ter um tipo de dados separado.
Haveria uma definição independente de idioma dos símbolos e um motivo para tê-los em outros idiomas?
Symbolé um tipo de dados que denota o conceito de nome ou rótulo . Symbols são objetos de valor , imutáveis, geralmente imediatos (se a linguagem distingue uma coisa dessas), apátridas e sem identidade. Dois Symbols iguais são também garantidos idênticos, ou seja, dois Symbols iguais são na verdade o mesmo Symbol. Isso significa que igualdade de valor e igualdade de referência são a mesma coisa e, portanto, igualdade é eficiente e O (1).
Os motivos para tê-los em um idioma são realmente os mesmos, independentemente do idioma. Alguns idiomas dependem mais deles do que outros.
Na família Lisp, por exemplo, não há conceito de "variável". Em vez disso, você tem Symbols associados a valores.
Em linguagens com capacidades reflexivas ou introspectivos, Symbols muitas vezes são usados para indicar os nomes das entidades reflectidas nas APIs de reflexão, por exemplo, em Ruby, Object#methods, Object#singleton_methods, Object#public_methods, Object#protected_methods, e Object#public_methodsretornar um Arrayde Symbols (embora eles poderiam muito bem retornar um Arrayde Methods). Object#public_sendusa um Symboldenotando o nome da mensagem a ser enviada como argumento (embora também aceite um String, Symbolseja mais semanticamente correto).
No ECMAScript, Symbols são um alicerce fundamental para tornar o ECMAScript seguro para os recursos no futuro. Eles também desempenham um grande papel na reflexão.