Като разработчици ние и двамата сме запознати и се чувстваме комфортно с разделението между писане на код и изпълнение на код. Можем да отворим текстов редактор и да напишем някакъв код, но в повечето езици не се очаква, че актът на писане на код ще направи нещо. Имаме отделен процес, който ще изпълни кода. Някои езици избират да изискват стъпка на компилиране (Java, C#, Go, Haskell и т.н.) преди изпълнение, а някои позволяват директно изпълнение (Javascript, Python, Ruby и т.н.), но във всички тези случаи има твърда бариера между кодиране и изпълнение на кода.

Разширяване на абстракцията

Ами ако добавим друг интерпретатор в нашите слоеве на абстракция? Какво би направило това?

Това не е толкова луда идея.

Java прави това от години. Java има сервлет контейнери, EJB контейнери и OSGi. .Net има IIS, който има подобни свойства на различни Java контейнери (да не се бърка с Docker контейнери). Има много примери за това, че кодът управлява жизнения цикъл на друг код.

С ефектите като данни ще използваме много специфичен подход. Ще създадем няколко стека от ефекти (стек първи влязъл, първи излязъл (FIFO) — така че наистина опашка, името не е по моя вина), които по-късно ще преминем през интерпретатори.

Ефектите, които ще поставим в нашия стек, ще бъдат измислен език, който ще създадем (ефекти като рамка за данни може да идва с някои често използвани ефекти). Този език ще бъде специфичен за домейн език (DSL), който ще съдържа команди, които са полезни за създаване на решение на проблема, който създаваме софтуер за разрешаване.

В съответствие с DSL програмирането, ние първо ще разработим език, който прави решаването на нашия проблем лесен и след това ще напишем нашето решение на този език. Много по-лесно е, отколкото изглежда.

Този нов език ще се управлява чрез интерпретатор, който или сме написали на нашия нормален език за програмиране, или който ни е предоставен от рамката. Много рамки изискват от нас да напишем манипулатор за всяка команда в нашия DSL. Някои рамки ни позволяват да настроим различни интерпретатори за различни ситуации. Представете си, че имате един интерпретатор за производство и друг за тестване. Вместо да се подиграваме, можем да напишем манипулатор на тест, който има предвидимо поведение, подходящо за тестване.

Ползи

Има място за оптимизации. При продължителна сесия интерпретаторът може да научи за програмата, която изпълнява, и да направи оптимизации на начина, по който изпълнява програмата.

Има място за добавяне на телеметрични данни, които се събират автоматично и не трябва да се обработват в самия код. Помислете за всички неща, обещани от аспектно ориентираното програмиране и сега имате къде да поставите тези неща.

Конкретен начин за внедряване и използване на DSL.

Страничните ефекти се случват в манипулатори, а не във вашия DSL. Можете да изпитате радостта от разработката без странични ефекти, когато използвате вашите команди.

Тестването става лесно. Можете да тествате изолацията на всяка двойка команда/манипулатор и да използвате алтернативни манипулатори вместо подигравка. Писането на специален манипулатор за тест се чувства супер естествено.

Опитвам го

Има три добри места за изследване на тази концепция.

  • Бряст
  • „Ефекти като данни“
  • Безплатни монади

Elm е език от страна на сървъра, който е изграден с ефекти като парадигма на данни, вградена в езика.

Effects As Data е най-добрата Javascript рамка, за която никога не сте чували. Написан е от талантлив разработчик на име Франки О’Рурк и е създаден, за да бъде много използваем.

Безплатните монади са твърда функционална реализация на тези идеи. Няколко езика имат библиотеки Free Monad. Това е най-малко достъпната, но най-мощната опция от трите.

Заключение

Effects as Data ви позволява да напишете DSL, който ще се изпълнява чрез интерпретатор в кода. Този интерпретатор може да добави стойност по време на изпълнение и да улесни тестването. Има много реализации и по-достъпните са доста лесни за започване.