Так, справді є. Типу.
Newspeak не має статичного стану і глобального стану. Це означає, що єдиний можливий спосіб отримати доступ до залежності - це явно ввести його. Очевидно, це означає, що мові, або у випадку з Newspeak, точніше, IDE потрібно зробити ін'єкцію залежності простою, інакше мова буде непридатною.
Отже, мова не розрахована на DI, швидше необхідність для DI є наслідком мовної конструкції.
Якщо немає статичного стану і немає глобального стану, то ви не можете просто "дотягнутися" до ефіру і щось витягнути. Наприклад, у Java структура пакету є статичним станом. Я просто можу сказати, java.lang.String
і у мене є String
клас. Це неможливо в Newspeak. Все, з чим ви працюєте, повинно бути надано вам явно, інакше ви просто не зможете отримати це. Отже, все - залежність, і кожна залежність явна.
Ви хочете рядок? Ну, ви повинні спочатку попросити stdlib
об'єкт, щоб вам String
вручив клас. О, але як отримати доступ до stdlib
? Ну, спершу вам потрібно попросити platform
надати вам stdlib
об’єкт. О, але як отримати доступ до platform
? Ну, ви повинні спочатку попросити когось іншого, щоб він передав вам platform
предмет. О, але як отримати доступ до того, хто хто здає в оренду? Ну, ви повинні спочатку попросити ще когось, хто вам здасть об’єкт.
Наскільки далеко в кролячій норі йде це? Де зупиняється рекурсія? Взагалі, власне. Це не зупиняється. Потім, як можна написати програму в Newspeak? Ну, строго кажучи, ви не можете!
Вам потрібна якась поза сутність, яка пов’язує все це разом. У Newspeak ця сутність є IDE. IDE бачить всю програму. Він може з'єднати різні частини разом. Стандартний зразок в Newspeak полягає в тому, що центральний клас вашої програми має аксесуар, який називається platform
, і Newspeak IDE вводить об'єкт в цей доступ, який має методи, які повертають деякі основні потреби програмування: String
клас, Number
клас, Array
клас, і так далі.
Якщо ви хочете перевірити свою програму, ви можете ввести platform
об'єкт, File
метод якого повертає клас з манекеновими методами. Якщо ви хочете розгорнути свою програму в хмару, ви вводите платформу, File
клас якої насправді підтримується Amazon S3. Міжплатформні графічні інтерфейси працюють, вводячи різні рамки графічного інтерфейсу для різних ОС. Newspeak навіть має експериментальний компілятор Newspeak-ECMAScript та підтримуваний HTML графічний інтерфейс, що дозволяє переносити повнофункціональний додаток GUI з рідного робочого столу в браузер без змін, просто вводячи різні елементи GUI.
Якщо ви хочете розгорнути свою програму, IDE може серіалізувати програму в об’єкт на диску. (На відміну від свого предка, Smalltalk, Newspeak має формат серіалізації об'єкта поза зображенням. Не потрібно брати з собою все зображення саме тому, що всі залежності вводяться: IDE точно знає , в яких частинах системи вашої програми використовує, а що ні. Отже, він серіалізує саме підключений підграф об'єктного простору, що містить вашу програму, нічого більше.)
Все це працює просто шляхом виведення об'єктної орієнтації на крайність: все - це виклик віртуального методу ("відправка повідомлення" в термінології Smalltalk, нащадок якого Newspeak). Навіть пошук суперкласу - це виклик віртуального методу! Візьміть щось подібне
class Foo extends Bar // using Java syntax for familiarity
або, по-новому:
class Foo = Bar () () : ()
У Java це створить ім'я Foo
в статичному глобальному просторі імен, а також знайдеться Bar
у статичній глобальній просторі імен та складе Bar
Foo
суперклас. Навіть у Ruby, який набагато більш динамічний, це все одно створить статичну константу в глобальному просторі імен.
У Newspeak еквівалентне оголошення означає: створити метод getter з назвою Foo
і змусити його повернути клас, який шукає його суперклас, викликаючи метод з ім'ям Bar
. Примітка: це не так, як Ruby, де ви можете помістити будь-який виконуваний код Ruby як декларування надкласового класу, але код буде виконаний лише один раз, коли створено клас і повернене значення цього коду стане фіксованим надкласом. Ні. Метод Bar
викликається для кожного пошуку методу!
Це має певні глибокі наслідки:
- оскільки міксин - це в основному клас, який ще не знає свого надкласу, а в Newspeak суперклас - це динамічний виклик віртуального методу, і, таким чином, невідомий, кожен клас автоматично також є mixin. Ви отримуєте міксин безкоштовно.
оскільки внутрішній клас - це лише виклик методу, який повертає клас, ви можете замінити цей метод у підкласі зовнішнього класу, тому кожен клас є віртуальним. Ви отримуєте віртуальні заняття безкоштовно:
class Outer {
class Inner { /* … */ }
}
class Sub extends Outer {
override class Inner { /* … */ }
}
Новомовна мова:
class Outer = () (
class Inner = () () : ()
) : ()
class Sub = Outer () (
class Inner = () () : ()
) : ()
оскільки суперклас - це лише виклик методу, який повертає клас, ви можете замінити цей метод у підкласі зовнішнього класу, внутрішні класи, визначені в надкласі, можуть мати інший надклас у підкласі. Ви отримуєте спадщину ієрархії класів безкоштовно:
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`!!!
}
Новомовна мова:
class Outer = () (
class MyCoolArray = Array () () : ()
) : ()
class Sub = Outer () (
class Array = () () : ()
) : ()
і, нарешті, найважливіше для цієї дискусії: оскільки (крім тих, які ви визначили у своєму класі, очевидно), ви можете викликати лише методи у вашому лексично огороджувальному класі (класах) та вашому суперкласі (класах), найвіддаленішому класі найвищого рівня взагалі не може викликати будь-які методи, за винятком тих, які явно вводяться: клас верхнього рівня не має класу, що закриває, методи якого він міг би викликати, і він не може мати суперклас, окрім типового, тому що декларація надкласу - це виклик методу, і він, очевидно, не може перейти до суперкласу (він єсуперклас), і він також не може перейти до лексично огороджувального класу, оскільки його немає. Це означає, що класи вищого рівня повністю інкапсульовані, вони можуть отримати доступ лише до того, що їм явно вводять, і їм вводять лише те, що вони прямо вимагають. Іншими словами: класи вищого рівня - це модулі. Ви отримуєте всю модульну систему безкоштовно. Насправді, якщо бути більш точним: класи вищого рівня - це декларації модулів, його екземпляри - модулі. Таким чином, ви отримуєте модульну систему з параметричними деклараціями модулів та першокласними модулями безкоштовно, що багато, навіть дуже складні, модульні системи не можуть зробити.
Для того, щоб зробити цю ін'єкцію безболісною, класові декларації мають незвичну структуру: вони складаються з двох декларацій. Перший - це конструктор класів, який є не конструктором, який конструює екземпляри класу, а швидше конструктором, який конструює середовище, в якому працює тіло класу. У синтаксисі, подібному до Java, це виглядатиме приблизно так:
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"
}
Новомовна мова:
class Foo using: platform = Bar (
Array = platform collections Array
String = platform streams String
File = platform files ExternalReadWriteStream
) (
class MyArray = Array () () : ()
) : ()
Зауважте, що спосіб програміста Newspeak насправді бачить класи (и) такий:
Я навіть не можу почати це робити справедливо. Вам доведеться пограти з цим самостійно. Гілад Браха виголосив пару розмов про різні аспекти системи, включаючи модульність. Він дав по-справжньому тривалі (2 години) розмови , перша година яких - ретельне ознайомлення з мовою, включаючи історію модульності. Розділ 2 платформи програмування новомовних програм охоплює модульність. Якщо ви скасуєте Newspeak на Squeak - Посібник для ошелешених (він же Newspeak-101) , ви відчуваєте систему. Newspeak by Example - це живий документ (тобто він працює всередині порту Newspeak-on-ECMASCript, кожен рядок коду можна редагувати, кожен результат перевіряти), демонструючи основний синтаксис.
Але дійсно, вам доведеться пограти з цим. Він просто настільки відрізняється від усіх основних і навіть більшості немейнстримних мов, що важко пояснити, це потрібно пережити.