Sim, de fato existe. Tipo de.
O Newspeak não tem estado estático nem estado global. Isso significa que a única maneira possível de obter acesso a uma dependência é injetá-la explicitamente. Obviamente, isso significa que a linguagem, ou no caso do Newspeak, mais precisamente, o IDE precisa facilitar a injeção de dependência, caso contrário, a linguagem será inutilizável.
Portanto, a linguagem não foi projetada para DI, mas sua necessidade é uma conseqüência do design da linguagem.
Se não houver um estado estático e nenhum estado global, você não pode simplesmente "alcançar" o éter e extrair algo. Por exemplo, em Java, a estrutura do pacote é estado estático. Eu posso apenas dizer java.lang.String
e eu tenho a String
classe. Isso não é possível no Newspeak. Tudo o que você trabalha tem que ser explicitamente fornecido a você, caso contrário, você simplesmente não conseguirá. Portanto, tudo é uma dependência e toda dependência é explícita.
Você quer uma corda? Bem, você deve primeiro pedir ao stdlib
objeto que lhe entregue a String
classe. Ah, mas como você tem acesso ao stdlib
? Bem, você deve primeiro pedir a platform
mão para entregar o stdlib
objeto. Ah, mas como você tem acesso ao platform
? Bem, você precisa primeiro pedir a alguém para lhe entregar o platform
objeto. Ah, mas como você tem acesso a alguém que mente? Bem, você precisa primeiro pedir a outra pessoa para lhe entregar o objeto.
Até onde fica a toca do coelho? Onde a recursão pára? Todo o caminho, na verdade. Isso não para. Então, como você pode escrever um programa no Newspeak? Bem, estritamente falando, você não pode!
Você precisa de alguma entidade externa que amarre tudo isso. No Newspeak, essa entidade é o IDE. O IDE vê o programa inteiro. Pode conectar as peças díspares. O padrão padrão no Newspeak é que a classe central do seu aplicativo tenha um acessador chamado platform
e o Newspeak IDE injeta um objeto nesse acessador que possui métodos que retornam algumas das necessidades básicas da programação: uma String
classe, uma Number
classe, uma Array
classe, e assim por diante.
Se você quiser testar seu aplicativo, poderá injetar um platform
objeto cujo File
método retorne uma classe com métodos fictícios. Se você deseja implantar seu aplicativo na nuvem, injeta uma plataforma cuja File
classe é realmente apoiada pelo Amazon S3. As GUIs de plataforma cruzada funcionam injetando diferentes estruturas de GUI para diferentes sistemas operacionais. O Newspeak ainda possui um compilador experimental Newspeak-to-ECMAScript e uma estrutura de GUI suportada por HTML que permite transportar um aplicativo de GUI com todos os recursos da área de trabalho nativa para o navegador sem alterações, apenas injetando diferentes elementos da GUI.
Se você deseja implantar seu aplicativo, o IDE pode serializar o aplicativo em um objeto em disco. (Diferentemente de seu ancestral, Smalltalk, o Newspeak possui um formato de serialização de objeto fora de imagem. Você não precisa levar a imagem inteira com você, precisamente porque todas as dependências foram injetadas: o IDE sabe exatamente quais partes do sistema seu aplicativo usa e que não usa. Portanto, serializa exatamente o subgrafo conectado do espaço de objeto que compreende seu aplicativo, nada mais.)
Tudo isso funciona simplesmente levando a orientação ao objeto ao extremo: tudo é uma chamada de método virtual ("envio de mensagem" na terminologia Smalltalk, da qual o Newspeak é um descendente). Até a pesquisa da superclasse é uma chamada de método virtual! Tome algo como
class Foo extends Bar // using Java syntax for familiarity
ou, no Newspeak:
class Foo = Bar () () : ()
Em Java, isso criará um nome Foo
no espaço para nome global estático e procurará Bar
no espaço para nome global estático e criará a Bar
Foo
superclasse. Mesmo no Ruby, que é muito mais dinâmico, isso ainda criará uma constante estática no espaço para nome global.
No Newspeak, a declaração equivalente significa: crie um método getter chamado Foo
e faça com que ele retorne uma classe que consulta sua superclasse chamando o método chamado Bar
. Nota: não é como Ruby, onde você pode colocar qualquer código Ruby executável como a declaração da superclasse, mas o código será executado apenas uma vez quando a classe for criada e o valor de retorno desse código se tornar a superclasse fixa. Não. O método Bar
é chamado para todas as pesquisas de método!
Isso tem implicações profundas:
- Como um mixin é basicamente uma classe que ainda não conhece sua superclasse, e no Newspeak, a superclasse é uma chamada de método virtual dinâmica e, portanto, desconhecida, toda classe também é automaticamente um mixin. Você ganha mixins de graça.
como uma classe interna é apenas uma chamada de método que retorna uma classe, você pode substituir esse método em uma subclasse da classe externa, para que cada classe seja virtual. Você recebe aulas virtuais de graça:
class Outer {
class Inner { /* … */ }
}
class Sub extends Outer {
override class Inner { /* … */ }
}
Newspeak:
class Outer = () (
class Inner = () () : ()
) : ()
class Sub = Outer () (
class Inner = () () : ()
) : ()
como a superclasse é apenas uma chamada de método que retorna uma classe, você pode substituir esse método em uma subclasse da classe externa, as classes internas definidas na superclasse podem ter uma superclasse diferente na subclasse. Você recebe a herança da hierarquia de classes gratuitamente:
class Outer {
class MyCoolArray extends Array { /* … */ }
}
class Sub extends Outer {
override class Array { /* … */ }
// Now, for instances of `Sub`, `MyCoolArray` has a different superclass
// than for instances of `Outer`!!!
}
Newspeak:
class Outer = () (
class MyCoolArray = Array () () : ()
) : ()
class Sub = Outer () (
class Array = () () : ()
) : ()
e, finalmente, o mais importante para esta discussão: como (além dos que você definiu em sua classe, obviamente), você só pode chamar métodos em suas classes lexicamente anexas e em suas superclasses, uma classe externa de nível superior não pode chamar nenhum método , exceto os injetados explicitamente: uma classe de nível superior não possui uma classe envolvente cujos métodos poderia chamar e não pode ter uma superclasse diferente da padrão, porque a declaração da superclasse é chamada de método, e obviamente não pode ir para a superclasse ( éa superclasse) e também não pode ir para a classe anexa lexicamente, porque não há nenhuma. O que isso significa é que as classes de nível superior são completamente encapsuladas, elas só podem acessar o que são explicitamente injetadas e apenas o que pedem explicitamente. Em outras palavras: as classes de nível superior são módulos. Você recebe todo um sistema de módulos gratuitamente. De fato, para ser mais preciso: as classes de nível superior são declarações de módulo, suas instâncias são módulos. Portanto, você obtém um sistema de módulo com declarações paramétricas e módulos de primeira classe gratuitamente, algo que muitos sistemas de módulos, mesmo muito sofisticados, não podem fazer.
Para tornar toda essa injeção indolor, as declarações de classe têm uma estrutura incomum: elas consistem em duas declarações. Um é o construtor da classe, que não é o construtor que constrói instâncias da classe, mas o construtor que constrói o ambiente em que o corpo da classe é executado. Em uma sintaxe semelhante a Java, seria algo como isto:
class Foo(platform) extends Bar {
Array = platform.collections.Array
String = platform.lang.String
File = platform.io.File
| // separator between class constructor and class body
class MyArray extends Array { /* … */ }
// Array refers to the method defined above which in turn gets it from the
// platform object that was passed into the class "somehow"
}
Newspeak:
class Foo using: platform = Bar (
Array = platform collections Array
String = platform streams String
File = platform files ExternalReadWriteStream
) (
class MyArray = Array () () : ()
) : ()
Observe que a maneira como um programador de Newspeak realmente verá as classes é assim:
Eu não posso nem começar a fazer justiça, no entanto. Você terá que brincar com você mesmo. Gilad Bracha deu algumas palestras sobre vários aspectos do sistema, incluindo a modularidade. Ele fez uma palestra muito longa (duas horas) , cuja primeira hora é uma introdução completa ao idioma, incluindo a história da modularidade. O capítulo 2 da plataforma de programação Newspeak cobre a modularidade. Se você der uma olhada no Newspeak no Squeak - um guia para os perplexos (também conhecido como Newspeak-101) , terá uma ideia do sistema. O Newspeak por exemplo é um documento ativo (ou seja, está sendo executado dentro da porta Newspeak-on-ECMASCript, todas as linhas de código são editáveis, todos os resultados são inspecionáveis) demonstrando a sintaxe básica.
Mas realmente, você tem que brincar com isso. É tão diferente de todas as linguagens convencionais e até da maioria das linguagens não convencionais que é difícil de explicar que precisa ser experimentado.