Características da LinguagemNúcleo vs Implementação de Biblioteca
D oferece várias capacidades nativas à linguagem núcleo que são implementadas como bibliotecas em outras linguagens como C++:- Arrays Dinâmicos
- Strings
- Arrays Associativos
- Números Complexos
Algumas observações gerais iniciais:
- Cada uma delas é altamente usada. Isso significa que até pequenas melhorias em usabilidade são válidas para se alcançar.
- Ser uma característica da linguagem núcleo significa que o compilador emitir melhor e mais mensagens de erro quando um tipo é usado incorretamente. Implementações de biblioteca tendem a notoriamente mensagens obtusas baseadas nos detalhes internos dessas implementações.
- Características de biblioteca não podem inventar nova sintaxe, novos operadores, ou novos tokens (símbolos).
- Implementações de biblioteca tendem a precisar de muito processamento de tempo de compilação da implementação, novamente e novamente para cada compilação, o que resuz a velocidade de compilação.
- Implementações de biblioteca são supostas para prover flexibilidade para o usuário final. Mas se são padronizadas, padronizadas ao ponto de o compilador ser capaz de reconhecer-las como especiais (o Padrão C++ permite isso), então elas se tornam inflexiveis como características nativas ao núcoleo.
- A habilidade de definir novos tipos de biblioteca, enquanto teve grandes avanços nos últimos anos, ainda deixa muito para ser desejada em integrar suavemente na linguagem existente. Extermidades ásperas, sintaxe desajeitada, e casos de canto estranho abundam.
Arrays Dinâmicos
C++ tem arrays nativos ao núcleo. Mas eles não trabalham muito bem. Ao invés de consertá-los, muitos tipos diferentes de arrays foram criados como parte da Biblioteca Padrão de Gabaritos (STL) do C++, cada um cobrindo uma deficiência diferente nos arrays nativos. Estes incluem:- basic_string
- vector
- valarray
- deque
- slice_array
- gslice_array
- mask_array
- indirect_array
Como sempre, um tipo nativo ao C++ nos deica criar açucar sintático para ele. Isso começa com ter um array literal, e segue com alguns novos operadores específicos para arrays. Uma implementação de array de biblioteca deve fazer tudo sobrecarregando os operadores existentes. O operador de indexação, a[i], é compartilhado com C++. Fomado está o operador de concatenação de arrays ~, operador de junção de arrays ~=, operador de fatia do array a[i..j], e o operador de vetor do array a[].
Os operadores de concatenação ~ e ~= resolvem um problema que vem quando somente operadores esxistentes podem ser sobrecarregados. Normalmente, + é pressionado em serviço como concarenação para implementações de array de biblioteca. Mas isso venta impedindo + de significar soma de vetor de array. Além disso, concatenação não tem nada em comum com adição, e usar o mesmo operador para ambos é confuso.
Strings
Uma comparação detalhada com std::string do C++. C++ tem, é claro, suporte nativo à strings na forma de strings literais e arrays de char. Elas sofrem de todas as fraquezas dos arrays nativos em C++.Mas depois de tudo, o que é uma string senão um array de caracteres? Se os problemas de arrays nativos forem consertados, não são resolvidos os problemas com strings também? Sim. A princípio parece estranho que D não tenha uma classe string, mas já que maniipular strings não é nada além de manupular arrays de caracteres, se arrays trabalham, não há nada que uma classe string acrescente a eles.
Além disso, os esquisitos resultados de strings literais nativas não serem do mesmo tipo que uma classe de biblioteca string vão embora.
Arrays Associativos
O principal benefício disso é, mais uma vez, açocar sintático. Um array associativo chaveando com um tipo T e armazenando um valor int é naturalmente escrito com:int[T] foo;ao invés de:
import std.associativeArray;Arrays associativos nativos também oferecem a possibilidade de ter literais de arrays associativos, que são uma característica adicional freqüêntemente pedida.
...
std.associativeArray.AA!(T, int) foo;
Números Complexos
Uma comparação detalhada com std::complex do C++.A razão mais constrangedora é compatibilidade com tipos de ponto flutuante complexos e imaginários do C. Depois, é a habilidade de ter ponto flutuante imaginário literal. Não é:
c = (6 + 2i - 1 + 3i) / 3i;mais preferível que escrever:
c = (complex!(double)(6,2) + complex!(double)(-1,3)) / complex!(double)(0,3);? Não há nenhum contestamento.