Tak, rzeczywiście jest. Raczej.
Newspeak nie ma stanu statycznego ani globalnego. Oznacza to, że jedynym możliwym sposobem uzyskania dostępu do zależności jest jawne jej wstrzyknięcie. Oczywiście oznacza to, że język, a dokładniej IDE, musi ułatwić zastrzyk zależności, w przeciwnym razie język będzie bezużyteczny.
Tak więc język nie jest przeznaczony do DI, a konieczność DI jest konsekwencją projektu języka.
Jeśli nie ma stanu statycznego ani globalnego, nie możesz po prostu „wyciągnąć” do eteru i wyciągnąć coś. Na przykład w Javie struktura pakietu jest statyczna. Mogę tylko powiedzieć java.lang.String
i mam String
klasę. To nie jest możliwe w Newspeak. Wszystko , z czym pracujesz, musi być ci wyraźnie przekazane, w przeciwnym razie po prostu nie będziesz w stanie tego zrobić. Tak więc wszystko jest zależnością, a każda zależność jest jawna.
Chcesz sznurka? Cóż, najpierw musisz poprosić stdlib
obiekt o przekazanie String
klasy. Och, ale jak uzyskać dostęp do stdlib
? Cóż, musisz najpierw poprosić platform
o przekazanie ci stdlib
obiektu. Och, ale jak uzyskać dostęp do platform
? Musisz najpierw poprosić kogoś innego o przekazanie ci platform
przedmiotu. Och, ale jak uzyskać dostęp do tego, żeby ktoś się nie dowiedział? Cóż, najpierw musisz poprosić kogoś innego o przekazanie ci przedmiotu.
Jak daleko to sięga do króliczej nory? Gdzie kończy się rekurencja? Właściwie przez całą drogę. To się nie kończy. Jak zatem napisać program w Newspeak? Ściśle mówiąc, nie możesz!
Potrzebujesz jakiegoś zewnętrznego bytu, który łączy to wszystko razem. W Newspeak tym podmiotem jest IDE. IDE widzi cały program. Może łączyć ze sobą różne elementy. Standardowy wzorzec w aplikacji Newspeak polega na tym, że klasa centralna aplikacji ma wywoływany akcesor platform
, a IDE Newspeak wstrzykuje do tego obiektu obiekt, który ma metody zwracające niektóre z podstawowych potrzeb programowania: String
klasa, Number
klasa, Array
klasa, i tak dalej.
Jeśli chcesz przetestować aplikację, możesz wstrzyknąć platform
obiekt, którego File
metoda zwraca klasę metodami pozorowanymi. Jeśli chcesz wdrożyć aplikację w chmurze, wstrzykujesz platformę, której File
klasa faktycznie jest wspierana przez Amazon S3. Wieloplatformowe interfejsy GUI działają poprzez wstrzykiwanie różnych struktur GUI dla różnych systemów operacyjnych. Newspeak ma nawet eksperymentalny kompilator Newspeak-to-ECMAScript i ramę GUI opartą na HTML, która pozwala na przenoszenie w pełni funkcjonalnej aplikacji GUI z natywnego pulpitu do przeglądarki bez zmian, po prostu przez wstrzyknięcie różnych elementów GUI.
Jeśli chcesz wdrożyć aplikację, IDE może serializować aplikację do obiektu na dysku. (W przeciwieństwie do swojego przodka, Smalltalk, Newspeak ma format serializacji poza obrazem. Nie musisz zabierać całego obrazu ze sobą, właśnie dlatego, że wstrzykiwane są wszystkie zależności: IDE dokładnie wie , które części systemu twoja aplikacja używa, a czego nie. Tak więc serializuje dokładnie podłączony podgrupa przestrzeni obiektów, która zawiera twoją aplikację, nic więcej.)
Wszystko to działa po prostu poprzez skrajne zorientowanie obiektowe: wszystko jest wirtualnym wywołaniem metody (termin „wysyłanie wiadomości” w terminologii Smalltalk, którego potomkiem jest Newspeak). Nawet wyszukiwanie nadklasy jest wirtualnym wywołaniem metody! Weź coś takiego
class Foo extends Bar // using Java syntax for familiarity
lub w Newspeak:
class Foo = Bar () () : ()
W Javie spowoduje to utworzenie nazwy Foo
w statycznej globalnej przestrzeni nazw, wyszukiwanie Bar
w statycznej globalnej przestrzeni nazw i tworzenie Bar
Foo
nadklasy. Nawet w Ruby, który jest znacznie bardziej dynamiczny, nadal będzie tworzyć stałą statyczną w globalnej przestrzeni nazw.
W Newspeak równoważna deklaracja oznacza: utwórz metodę gettera o nazwie Foo
i spraw, aby zwróciła klasę, która wyszukuje swoją nadklasę, wywołując metodę o nazwie Bar
. Uwaga: to nie jest jak Ruby, gdzie można umieścić dowolny wykonywalny kod Ruby jako deklarację nadklasy, ale kod zostanie wykonany tylko raz, gdy klasa zostanie utworzona, a zwracana wartość tego kodu stanie się stałą nadklasą. Nie. Metoda Bar
jest wywoływana dla każdego pojedynczego wyszukiwania metody!
Ma to głębokie implikacje:
- ponieważ mixin jest w zasadzie klasą, która jeszcze nie zna swojej nadklasy, a w Newspeak superklasa jest dynamicznym wirtualnym wywołaniem metody, a zatem nieznana, każda klasa automatycznie jest również miksem. Dostajesz mixiny za darmo.
ponieważ klasa wewnętrzna jest tylko wywołaniem metody, która zwraca klasę, możesz zastąpić tę metodę w podklasie klasy zewnętrznej, więc każda klasa jest wirtualna. Otrzymujesz wirtualne zajęcia za darmo:
class Outer {
class Inner { /* … */ }
}
class Sub extends Outer {
override class Inner { /* … */ }
}
Gazeta:
class Outer = () (
class Inner = () () : ()
) : ()
class Sub = Outer () (
class Inner = () () : ()
) : ()
ponieważ nadklasa jest tylko wywołaniem metody, która zwraca klasę, można przesłonić tę metodę w podklasie klasy zewnętrznej, klasy wewnętrzne zdefiniowane w nadklasie mogą mieć inną podklasę w podklasie. Otrzymujesz dziedziczenie hierarchii klas za darmo:
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`!!!
}
Gazeta:
class Outer = () (
class MyCoolArray = Array () () : ()
) : ()
class Sub = Outer () (
class Array = () () : ()
) : ()
i na koniec najważniejsze w tej dyskusji: ponieważ (oprócz tych, które zdefiniowałeś w swojej klasie, oczywiście) możesz wywoływać metody tylko w klasie (klasach) leksykalnie otaczającej i swojej (klasach) superklasie, najbardziej zewnętrznej klasie najwyższego poziomu nie można wywołać żadnych metod na wszystkich z wyjątkiem tych, które są wyraźnie wstrzykiwana: klasa najwyższego poziomu nie ma klasę otaczającą którego metody mogą to nazwać, i nie może mieć superklasę innego niż domyślny, ponieważ deklaracja nadklasą jest wywołanie metody i oczywiście nie może przejść do nadklasy (tak jestnadklasa), a także nie może przejść do klasy zamykającej leksykalnie, ponieważ nie ma żadnej. Oznacza to, że klasy najwyższego poziomu są całkowicie enkapsulowane, mają dostęp tylko do tego, co zostały im wstrzyknięte, i otrzymują tylko to, o co wyraźnie proszą. Innymi słowy: klasy najwyższego poziomu są modułami. Otrzymujesz cały system modułów za darmo. Mówiąc dokładniej: klasy najwyższego poziomu są deklaracjami modułów, jego instancje są modułami. Otrzymujesz więc system modułowy z parametrycznymi deklaracjami modułów i moduły pierwszej klasy za darmo, czego nie może zrobić wiele, nawet bardzo wyrafinowanych systemów modułowych.
Aby uczynić cały ten zastrzyk bezbolesnym, deklaracje klasowe mają niezwykłą strukturę: składają się z dwóch deklaracji. Jednym z nich jest konstruktor klasy, który nie jest konstruktorem konstruującym instancje klasy, ale konstruktorem konstruującym środowisko, w którym działa ciało klasy. W składni podobnej do Java wyglądałby mniej więcej tak:
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"
}
Gazeta:
class Foo using: platform = Bar (
Array = platform collections Array
String = platform streams String
File = platform files ExternalReadWriteStream
) (
class MyArray = Array () () : ()
) : ()
Zauważ, że sposób, w jaki programista Newspeak rzeczywiście zobaczy klasy (klasy), wygląda następująco:
Ale nie mogę nawet zacząć tego robić sprawiedliwie. Będziesz musiał się z tym bawić. Gilad Bracha wygłosił kilka rozmów na temat różnych aspektów systemu, w tym modułowości. Wygłosił naprawdę długą (2- godzinną ) rozmowę , której pierwsza godzina to dokładne wprowadzenie do języka, w tym historia modułowości. Rozdział 2 platformy programistycznej Newspeak dotyczy modułowości. Jeśli przejrzysz Newspeak na Squeak - A Guide for the Confplexed (alias Newspeak-101) , poczujesz system. Przykład Gazety według Przykładu jest dokumentem na żywo (tzn. Działa wewnątrz portu Newspeak-on-ECMASCript, każdy wiersz kodu jest edytowalny, każdy wynik można sprawdzić), wykazując podstawową składnię.
Ale tak naprawdę musisz się z tym bawić. To jest po prostu tak różne od wszystkich nurtu, a nawet większość języków spoza głównego nurtu, że jest to trudne do wyjaśnienia, to musi być doświadczony.