portaldacalheta.pt
  • Основен
  • Kpi И Анализ
  • Инвеститори И Финансиране
  • Други
  • Финансови Процеси
Back-End

Декларативно програмиране Наистина ли съществува?



Понастоящем декларативното програмиране е доминиращата парадигма на набор от разнообразни и обширни домейни като: бази данни, шаблони и управление на конфигурацията.

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



Въпреки че тази парадигма е голямо подобрение спрямо императивния подход, който замени, бих могъл да кажа, че декларативното програмиране има значителни ограничения, ограничения, които смятам да проуча в тази статия. Освен това предлагам двустранен подход, който включва предимствата на декларативното програмиране, като същевременно преодолява неговите ограничения.



ПРОТЕСТ : Тази статия е написана в резултат на многогодишна лична борба с декларативни инструменти. Много от нещата, които той твърди, не са напълно доказани, а някои са представени като номинал. Правилната критика на декларативното програмиране ще отнеме много време, усилия и ще трябва да се върна назад и да използвам много от тези инструменти, но сърцето ми не би било в усилията. Смисълът на тази статия е да споделя мислите си с вас, без караница, просто ще покажа какво ми е подействало. Ако сте се борили с възходи и падения с декларативни инструменти за програмиране, тогава може да намерите малко удобство и някои алтернативи. И ако харесвате тази парадигма и нейните инструменти, не ми обръщайте много внимание.



Ако декларативното програмиране работи за вас Нямам право да ви казвам друго .

Може да мразите или обичате декларативното програмиране, но не можете да си позволите да го игнорирате.



Може да мразите или обичате декларативното програмиране, но не можете да си позволите да го игнорирате. Tweet

Предимствата на декларативното програмиране

Преди да проуча ограниченията на декларативното програмиране, намирам за необходимо да разбера неговите достойнства.

Несъмнено най-ефективният инструмент за декларативно програмиране е релационната база данни (RDB). релационна база данни ). Може дори да се счита за първия декларативен инструмент. Както и да е, RDB има две свойства, които смятате за архетип на декларативното програмиране:



ръководство за стил на материален дизайн на google
  • Специфичен за домейн език (DSL) : универсалният интерфейс за релационни бази данни е това DSL: Структуриран език за заявки , по-известен като SQL.
  • DSL крие слоеве от ниско ниво от потребителя : от Едгар Ф. Код публикува статията си за RDB Стана съвсем ясно, че целта на този модел е да разграничи желаните заявки от основните цикли, индекси и пътища, които ги изпълняват.

Преди RDB, повечето системи за бази данни могат да бъдат достъпни чрез императивен код, който е невероятно зависим от подробности на ниско ниво, като записи, индекси и физически пътища до самите данни. Тъй като тези елементи се променят след определено време, кодът може да спре да работи поради някаква основна промяна в структурата на данните. Кодът, който ви остава в резултат, е труден за писане, отстраняване на грешки, четене и труден за поддръжка. Най-вероятно кодът беше много дълъг, пълен с много дълги условия, повторения и може би някои грешки, които не бяха забележими, но зависеха от държавата.

Ако случаят беше такъв, RDB осигуриха много голям скок на производителността за разработчиците на системи. Сега, вместо да имате хиляди редове императивен код, можете да имате дефинирана схема на данни и също стотици (или дори няколко) заявки. В резултат на това приложенията трябва да се справят само с абстрактно, смислено и трайно представяне на данните; и свързването му чрез мощен и в същото време прост език за заявки. RDB вероятно е помогнал за увеличаване на производителността на програмистите, както и на компаниите, които са ги наели, с порядък.

Какви са най-честите предимства на декларативното програмиране?

Привържениците на декларативното програмиране винаги бързо споменават неговите предимства. Дори тези хора обаче признават, че това идва с определени компромиси.

Привържениците на декларативното програмиране винаги бързо споменават неговите предимства. Дори тези хора обаче признават, че това идва с определени компромиси. Tweet
  1. Четливост / използваемост : DSL обикновено е по-близо до естествен език (като английски или испански), отколкото до псевдокод и следователно е по-лесен за четене и изучаване от хора, които не са програмисти.
  2. Сбитост : По-голямата част от табулатурата се извлича от DSL, като по този начин остават по-малко редове, за да се извърши същата работа.
  3. Повторно използване : по-лесно е да създадете код, който може да се използва за различни цели; нещо, което всеки знае, е изключително трудно, когато се използват императивни конструкции.
  4. Idempotencia : можете да работите с крайни състояния и оставете програмата да свърши останалото. Например при операция на нагоре можете да вмъкнете ред, ако го няма, или можете да го модифицирате, ако вече е там, вместо да пишете код, който се грижи и за двата случая.
  5. Грешка при възстановяване : Лесно е да се идентифицира компилация, която ще спре при първата грешка, вместо да се налага да добавяте списъци с грешки за всяка възможна грешка. (Ако някога сте писали 3 обратни обаждания или обратно извикване вложен в node.js, за да знаете за какво е говорил.)
  6. Референтна прозрачност Въпреки че това предимство е свързано повече с функционалното програмиране, истината е, че то е валидно за всеки подход, който свежда до минимум ръчната манипулация на състоянието и се основава на странични ефекти.
  7. Комутативност - Възможността да се изрази крайно състояние, без да се посочва действителният ред, в който ще бъде приложено.

Въпреки че горните предимства са много често срещани, когато говорим за декларативно програмиране, ще ги обобщя в две качества, които ще служат като ръководни принципи при предлагането на алтернативен подход. Въпреки че горните са всички често цитирани предимства на декларативното програмиране, бих искал да ги събера в две качества, които ще служат като ръководни принципи, когато предлагам алтернативен подход.

  1. Слой на високо ниво, съобразен с конкретен домейн - Декларативното програмиране създава слой от най-високо ниво, използвайки информация от домейна, за който се отнася. Определено, ако използваме база данни, това е защото искаме набор от операции за обработка на данни. Повечето от 7-те предимства, споменати по-горе, идват от създаването на слой от високо ниво, който е специално проектиран за проблем с домейн.
  2. Пока-иго (безпроблемно) - Високо ниво, съобразено с домейн, крие задължителните подробности за изпълнението. Което означава, че ще направите по-малко грешки, тъй като детайлите на системата от ниско ниво не са достъпни. Това ограничение премахва много Уроци грешки във вашия код.

Два проблема с декларативното програмиране

В следващите два раздела ще обсъдя два от основните проблеми с декларативното програмиране: разделяне Y. липса на разполагане . Всеки преглед се нуждае от лош човек и затова ще използвам шаблон на HTML система като точен пример за недостатъците на декларативното програмиране.

Проблемът с разделянето на DSL

Представете си, че трябва да напишете уеб приложение с нетривиален брой посещения. Кодирането на тези посещения в набор от HTML файлове не е опция, тъй като много компоненти на тези страници се променят.

Най-бързото решение, което би било да се генерира HTML чрез конкатенационни низове, всъщност ви изглежда ужасно и веднага ще започнете да търсите алтернатива. Стандартното решение е да се използва шаблонна система. Въпреки че съществуват различни видове системи с шаблони, засега ще оставим техните разлики настрана за тази дискусия. Можем да ги разглеждаме като подобни, когато става въпрос за шаблони системи, за да предоставят алтернатива на кодирането на кодиране на HTML низове, като се използват условни и цикли. Точно както RDB се появиха като алтернатива на обвързването чрез контури чрез записи на данни.

Да предположим, че избираме стандартната шаблонна система; В това ще намерите три източника на триене, които ще посоча във възходящ ред в зависимост от тяхното значение. Първото би било, че шаблонът трябва да се намира в отделен файл от вашия код. Тъй като системата с шаблони използва DSL, синтаксисът е различен и следователно не може да бъде в един и същ файл. В простите проекти, където броят на файловете не е голям, необходимостта файловете от шаблони да се държат отделно е два или три пъти по-важна, защото надвишава броя на файловете.

Ще направя изключение с шаблоните Вграден Ruby (ERB за съкращението на английски Вградени шаблони за Ruby ) защото тези те са вградени в изходния код на Ruby. Но това не важи за инструменти, вдъхновени от ERB, написани на други езици, тъй като тези шаблони трябва да бъдат запазени в различни файлове.

Вторият източник на триене е, че DSL има собствен синтаксис, различен от този на езика за програмиране. Ето защо модифицирането на DSL (и дори писането на собствен) е много по-трудно. За да преминете под въжето и да смените инструмента, ще трябва да научите за токенизацията и разбор (разбор), които се считат за интересни и предизвикателни, но много трудни. Според мен това е недостатък.

Как може да се гледа DSL? Не е лесно, но може да се каже, че DSL е хубав чист слой при компилация от нисък клас.

Как може да се гледа DSL? Не е лесно, но може да се каже, че DSL е хубав чист слой при компилация от нисък клас. Tweet

Може би се чудите: „Защо, по дяволите, бихте искали да модифицирате инструмента си? Ако правите стандартен проект, добре написаният инструмент трябва да работи за вас. ' Може би да, или може би не.

DSL никога не притежава цялата сила на езика за програмиране. Ако го направи, няма да е DSL, а пълен език за програмиране.

Но не е ли целта на DSL? Фактът на не имаме целия контрол на програмен език вече на разположение и по този начин можем да получим абстракция и също така да премахнем повече източници на бъгове . Може би. както и да е най-много на DSL започват просто и постепенно започват да включват голям брой възможности на програмен език, докато не станат Стани един . Шаблонните системи са идеалният пример. Сега нека разгледаме стандартните характеристики на шаблонните системи и как те се свързват с възможностите на език за програмиране:

  • Заменете текста в шаблон : заместване на променлива.
  • Повтаряне на шаблон : цикли.
  • Избягвайте да отпечатвате шаблон, ако условието не отговаря : условни.
  • Частично : подпрограми.
  • Помощници : подпрограми (единствената разлика при частичните е, че помощниците могат да имат достъп до основния програмен език и да ви дадат свободата да излезете от DSL).

Когато казват, че DSL е ограничен, тъй като едновременно е алчност и отхвърля контрола върху езика за програмиране, това е пряко пропорционално на факта, че DSL функциите са съпоставими с характеристиките на програмен език . Що се отнася до SQL, това не е така, защото повечето от нещата, които SQL предлага, не изглеждат като това, което обикновено бихте намерили в език за програмиране. И в другия край на спектъра откриваме шаблони системи, при които на практика всяка функция кара DSL да се сближава ОСНОВЕН .

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

Разделянето е присъщ проблем на всеки DSL, независимо колко добре е проектиран.

И сега втори проблем с декларативните инструменти, който е общ, но не присъщ.

Друг проблем: Липсата на внедряване води до сложност

Ако бях написал статия преди няколко месеца, този раздел щеше да бъде извикан Повечето декларативни инструменти са # @! $ # @! Комплекс, но не знам защо . В процеса на писане на тази статия намерих по-добър начин да го изразя: Повечето декларативни инструменти са по-сложни, отколкото би трябвало . В този раздел ще обясня защо. За да анализирам сложността на даден инструмент, обичам да предлагам мярка, наречена граница на сложност . Границата на сложност е разликата между решаването на даден проблем с инструмент или решаването му на ниско ниво (уж прост императивен код), което инструментът се опитва да замени. Когато предишното решение е по-сложно от следващото, тогава се оказваме с граница на сложност. Когато кажа по-сложни Имам предвид повече редове код, код, който е по-труден за четене, модифициране и поддържане, но не непременно всички едновременно.

Имайте предвид, че не сравняваме решението на ниско ниво с най-добрия инструмент, а сравняваме с нито един инструмент. Това наподобява медицинския принцип на „Първо, няма да навредиш“ .

Признаци на инструмент с голяма граница на сложност:

  • Нещо, което би трябвало да отнеме няколко минути, за да се опише с много подробности в императивни условия, ще отнеме часове за кодиране с помощта на инструмента, дори ако знаете как да го използвате.
  • Започвате да чувствате, че работите около инструмента, вместо с него.
  • Трудно ви е да решите прост проблем, който очевидно принадлежи към домейна на инструмента, който използвате, но най-добрият отговор, който намирате в Преливане на стека единственото нещо, което описва е алтернатива .
  • Когато този прост проблем може да бъде разрешен с определена функция (която не съществува в инструмента) и видите библиотечен проблем на Github, който представя чудесна дискусия на тази функция с няколко +1 разпръснати.
  • Как се чувствате да почувствате неконтролируемото желание да оставите инструмента изцяло и да направите всичко сами в рамките на _ на цикъл_.

Може би се увличам от емоции, защото шаблонните системи не са така сложно, но тази относително малка степен на сложност не е достойна за неговия дизайн, вместо това областта на приложимостта е съвсем проста (не забравяйте, че ние генерираме HTML). Всеки път, когато същият подход се използва за по-сложен домейн (като управление на конфигурацията), границата на сложност може бързо да превърне вашия проект в тресавище.

Сега има изключения, при които не е напълно неприемливо инструментът да е малко по-сложен от ниското ниво, което искате да замените; ако инструментът дава код, който е по-четлив, кратък и правилен, може да си заслужава. Проблем е, когато инструментът е няколко пъти по-сложен от проблема, който замества, това е напълно неприемливо. Брайън Керниган е известен с това, че заяви: „ Това контролиране на сложността е същността на компютърното програмиране. ”Ако един инструмент само добавя значителна сложност към вашия проект, защо да го използвате?

И се чудим, защо някои декларативни инструменти са по-сложни от необходимото? Мисля, че би било грешка да се обвинява лош дизайн. Това е толкова общо обяснение, такъв ad-hominem аргумент към авторите на тези инструменти, че не е справедливо. Трябва да има друго обяснение, по-точно и информирано.

А сега малко оригами! Инструмент с интерфейс на високо ниво за абстрактно ниско ниво трябва да показва високото ниво отдолу.

А сега малко оригами! Инструмент с интерфейс на високо ниво за абстрактно ниско ниво трябва да показва високото ниво отдолу. Tweet

Моят аргумент е, че всеки инструмент, който предлага интерфейс от високо ниво за извличане на сура от ниско ниво да се разположи това по-високо ниво отдолу. Концепцията за да се разположи е включен в произведението на Кристофър Александър: 'Природата на реда' или Естеството на реда - по-специално том II. (Безнадеждно) е извън обхвата на тази статия (да не говорим, разбирам) да обобщим последиците от тази монументална работа върху софтуерния дизайн; въпреки че вярвам, че през следващите години въздействието му ще бъде огромно. Също така е извън обхвата на тази статия, за да предостави подробна дефиниция на процесите на внедряване. Но ще използвам концепцията за евристична форма .

Процесът на внедряване се състои от създаване на структура, без да се отрича съществуващата. На всяка стъпка всяка промяна (или диференциация, за да цитираме термините на Александър) остава в хармония с всяка предишна структура, когато предишната структура е просто кристализирана последователност от минали промени.

Най-интересното е това Unix това е отличен пример за разгръщане на по-високо ниво от едно отдолу. В Unix две сложни функции на операционната система, групови задачи и съпрограми (конвейри) са просто разширения на основните команди. За определени дизайнерски решения, като например превръщането на всичко в байтов поток, Shell a потребителска програма и I / O файловете са стандартни , Unix е в състояние да предостави тези функции толкова сложни, колкото и най-малко сложните. За да стресна защо тези примери за показване са отлични, ще цитирам някои откъси от Статия от 1979 г. От Денис Ричи, един от авторите на Unix:

Относно партидните задачи :

... Новата схема на процеса незабавно направи някои ценни функции тривиални за изпълнение; например отделен процес (с &) и рекурсивно използване на черупката като команда. Повечето системи трябва да доставят някакъв вид aplicación de trabajo en lote специална команда за интерпретатор и способност за файлове, различни от тези, използвани интерактивно.

Относно съвместните процедури :

Най-страхотното при тръбите на Unix е именно, че те са изградени от едни и същи постоянно използвани команди по прост начин.

Пионерите на Unix Денис Ричи и Кен Томпсън създадоха страхотна демонстрация за внедряване на тяхната операционна система. И те ни спасиха от дистопично бъдеще само с Windows като опция.

Пионерите на Unix Денис Ричи и Кен Томпсън създадоха страхотна демонстрация за внедряване на тяхната операционна система. И те ни спасиха от дистопично бъдеще само с Windows като опция. Tweet

Струва ми се, че тази елегантност и простота идва от процес на разполагане . Пакетните задачи и съпрограми се разполагат от предишни структури (командите работят в потребителска обвивка). Мисля, че поради минималистичната философия и ограничените ресурси на екипа, създал Unix, системата еволюира странично и като такава успя да включи разширени функции, без да разглежда отново най-основните, защото нямаше достатъчно ресурси за правене по друг начин.

При липса на процес на внедряване, високото ниво ще бъде значително по-сложно от необходимото. Тоест, сложността на повечето декларативни инструменти се развива от факта, че тяхното най-високо ниво не се разпростира от ниското ниво, което се опитват да заменят.

Тази липса на разгъване Ако пропуснете неологизма, това обикновено е оправдано от необходимостта да се защити потребителят от ниското ниво. Този акцент върху използването на poka-yoke (защита на потребителя от грешки на ниско ниво) идва на цена, което е граница на сложност, която се самоунищожава, защото допълнителната сложност ще генерира нови видове грешки. И за завършване, този вид грешки нямат нищо общо с проблема с домейна, а със самия инструмент. Няма да има преувеличение, ако опишем тези грешки като a ятрогения .

Инструментите за декларативни шаблони, когато се прилагат към задачата за генериране на HTML изгледи, са архетипен случай на високо ниво, отхвърлящо ниско ниво, което се претендира да отхвърли. Както добре? Защо генерирането на някакъв нетривиален изглед изисква логика и системите за шаблони, особено по-малко логичните, изцяло заобикалят логиката и след това се опитват да я изтласкат малко, когато смятат, че никой не гледа.

Забележка: още по-лоша обосновка за марж на сложност е, когато се опитват да продадат инструмент като магически или нещо, което просто върши работа ; ниското ниво на неяснота би трябвало да е нещо добро, защото магически инструмент винаги работи, без да знаете защо и как работи. Според моя опит, колкото по-вълшебен инструмент изглежда, толкова по-бързо ще превърне ентусиазма във разочарование.

А какво да кажем за разделянето на проблемите? Не трябва ли зрението и логиката да останат отделни? Най-честата грешка при това е да се приеме, че бизнес логиката и логиката на представяне са еднакви. Бизнес логиката няма никакъв смисъл в шаблона, но логиката на представяне съществува независимо от всичко. Заобикаляйки логиката на шаблона, логиката на презентацията се оставя настрана и я поставя на сървъра, където трябва да е тромаво, за да се адаптира. Всичко това ясно обяснение дължа на Алексей Боронин, който представя много добър случай в тази статия .

По мое мнение повече или по-малко две трети от работата на шаблона е в неговата логика на представяне, докато другата трета отговаря за справяне с общи проблеми като: конкатенационни низове, затворени тагове, специални избягващи символи и списъкът продължава. Това е двустранният характер на генерирането на HTML изгледи. Системите на отбора се грижат за второто полувреме, но не се справят много добре с първото полувреме. Шаблоните без логика обръщат гръб на този тип проблеми без колебание, принуждавайки ви да решите проблема. Други системи с шаблони страдат, защото всъщност трябва да предоставят нетривиален език за програмиране, така че техните потребители да могат да пишат логика на презентацията.

И накрая, декларативните инструменти за шаблони страдат от следното:

  • Ако се осмеляват да се разположат от проблема с домейна си, ще трябва да осигурят начини за генериране на логически модели;
  • DSL, който предоставя логика, всъщност не е DSL, а език за програмиране. Трябва да се отбележи, че други домейни, като управление на конфигурацията, също страдат от липса на „внедряване“.

Ще завърша този преглед с аргумент, който логически е откъснат от нишката, която носи тази статия, но който е много близо до сантименталното ядро: Имаме малко време за учене. Животът е кратък и освен това трябва да работим. Когато отговаряме на ограниченията си, трябва да отделяме време за изучаване на нови неща, които ще бъдат полезни и ще обслужват времето ни, дори когато сме изправени пред бърза технологична промяна. Ето защо ви съветвам да използвате инструменти, които не само предоставят решение, но всъщност обслужват домейна, за който се отнася. RDB ви учи за данни, а Unix ви учи за концепции на операционната система, но с незадоволителни инструменти, които не се разгръщат, винаги съм се чувствал така, сякаш съм научил тънкостите на неоптимално решение, докато съм в тъмното за същността на проблем за решаване.

Евристиката, която предлагам да разгледате сега, е ** инструменти за стойност, които осветяват проблема с вашия домейн, а не инструменти, които скриват проблема ви с домейна зад самонадеяните функции **.

Двойният подход

За да преодолея двата декларативни проблема с програмирането, които споменах тук, предлагам двойствен подход:

  • Използва специфичен език на структурата на домейна за данни (или dsDSL, за неговото съкращение на английски език) език на структурата на данните ) за преодоляване на раздялата.
  • Създайте високо ниво, което се разгръща от нивото отдолу, за да преодолеете границата на сложност.

dsDSL

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

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

инструменти за анализ на данни и визуализация

Ако бяхте попитали преди година, щях да мисля, че концепцията за dsDSL е идеалистична и тогава осъзнах, че JSON всъщност е чудесен пример за този подход! Анализираният JSON обект се състои от структури от данни, които декларативно представят входовете на данни, за да се възползват от DSL и също така да улеснят анализирането и обработката от език за програмиране. (Може да има други dsDSL в света, но дори не съм виждал такива. Ако знаете такива, бих се радвал да ги споделите в раздела за коментари.)

Подобно на JSON, dsDSL има следните атрибути:

  1. Състои се от малък набор от функции: JSON има две основни функции parse и stringify.
  2. Най-често срещаните му функции имат сложни и рекурсивни аргументи: анализираният JSON е масив или обект, който обикновено съдържа други масиви или обекти в него.
  3. Входните данни за тези функции съставят специфични представяния: JSON има изрична и строго наложена схема за проверка, която може да разграничи валидни структури от невалидни.
  4. Както входовете, така и изходите на тези функции могат да бъдат запазени и генерирани от език за програмиране, без да е необходим отделен синтаксис.

Но dsDSL надхвърля JSON в много отношения. Нека създадем dsDSL за генериране на HTML с помощта на Javascript. Тогава ще говоря за проблема дали този подход може да бъде разширен и на други езици (SPOILER: определено може да се направи в Ruby и Python, но вероятно не и в C).

HTML е език за маркиране, съставен от etiquetas разграничени от ъглови скоби (< и >). Тези маркери могат да бъдат незадължително съдържание и атрибути. Атрибутите са просто списък с ключови / прогнозни атрибути и съдържанието може да бъде текст или други тагове. Атрибутите и съдържанието не са задължителни за всеки етикет. Опростявам всичко това, но е доста добре.

Много лесен начин за представяне на HTML таг в dsDSL е използването на масив с три елемента: - Tag: низ. - Атрибути: обект (от тип ключ / проста оценка) или sin definir (ако не се изискват атрибути). - Съдържание: низ (текст), масив (друг етикет) или sin definir (ако няма съдържание).

Например, Index може да се запише като ['a', {href: 'views'}, 'Index'].

Ако искаме да поставим този котва елемент в div с links на клас, можем да напишем: ['div', {class: 'links'}, ['a', {href: 'views'}, 'Index']].

За да изброим няколко html тагове на едно и също ниво, бихме могли да ги поставим в масив:

[ ['h1', '!Hola!'], ['a', {href: 'views'}, 'Index'] ]

Същият принцип може да се приложи за създаване на множество маркери в рамките на един етикет:

['body', [ ['h1', '!Hola!'], ['a', {href: 'views'}, 'Index'] ]]

Разбира се, този dsDSL няма да ни бъде от голяма полза, ако не генерираме HTML от него. Нуждаем се от функция generar което ще накара dsDSL да създаде низ с HTML. Ето защо, ако изпълним generar (['a', {href: 'views'}, 'Index']), ще получим низа Index .

Идеята на всеки DSL е да посочи някои конструкции с определена структура, които след това да бъдат предадени на функция. В този случай структурата, която прави dsDSL, е този масив, който има един до три елемента; тези матрици имат специфична структура. Ако generar за да проверите вашите данни (и е важно и също така е лесно да ги потвърдите напълно, тъй като тези правила за валидиране са точната аналогия на синтаксиса на DSL), това ще ви каже точно къде сте сгрешили въведеното. След известно време ще започнете да разпознавате какво прави структурата валидна в dsDSL и тази структура ще бъде силно подсказваща за генерираното, което е в основата на нея.

Какви са достойнствата на dsDSL за разлика от DSL?

  • DsDSL е неразделна част от вашия код. Помага за по-малко броя на редовете, броя на файловете и цялостно намаляване на всичко.
  • DsDSL са лесно да анализира (и следователно по-лесно да се приложи и модифицира). Разбор това е просто итерация през елементи на масив или обект. По същия начин dsDSL са относително лесни за проектиране, защото вместо да създавате нов синтаксис (нещо, което всички биха мразели), можете да се придържате към синтаксиса на вашия програмен език (нещо, което също е мразено, но поне вече знаете какво е това ).
  • DsDSL има целия контрол върху езика за програмиране. Това означава, че dsDSL, когато се използва правилно, има предимствата на инструмент на високо ниво, както и на инструмент на ниско ниво.

Сега имаме последния аргумент, който е доста силен, поради което ще го подчертая в този раздел. Какво имам предвид под правилно наети ? За да видим как работи това, нека разгледаме пример, в който искаме да изградим таблица за показване на информацията от масив, наречен Сега, последното твърдение е силно, така че ще прекарам останалата част от този раздел DATA.

var DATA = [ {id: 1, descripción: 'Producto 1', precio: 20, onSale: verdadero, categorías: ['a']}, {id: 2, descripción: 'Producto 2', precio: 60, onSale: falso, categorías: ['b']}, {id: 3, descripción: 'Producto 3', precio: 120, onSale: falso, categorías: ['a', 'c']}, {id: 4, descripción: 'Producto 4', precio: 45, onSale: verdadero, categorías: ['a', 'b']} ]

В реално приложение DATA той ще бъде генериран динамично от заявка за база данни.

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

Искаме нашата маса да направи това:

  • Показване на заглавията на таблиците.
  • За всеки продукт ще се покажат полетата: описание, цена и категории.
  • Не отпечатвайте полето id но го добавете като атрибут id за всеки ред. АЛТЕРНАТИВНА ВЕРСИЯ: Добавете атрибут id за всеки елемент tr.
  • Поставете клас onSale ако продуктът се продава ( продава се ).
  • Сортирайте продуктите в низходящ ред по отношение на цената.
  • Филтрирайте определени продукти по категории. Ако FILTER е празен масив, ще покажем всички продукти. И ако не, ще покажем продуктите, където продуктовата категория се съдържа в FILTER.

Можем да създадем логическата презентация, която отговаря на това изискване, в ~ 20 реда код:

function drawTable (DATA, FILTER) { var printableFields = ['description', 'price', 'categories']; DATA.sort (function (a, b) {return a.price - b.price}); return ['table', [ ['tr', dale.do (printableFields, function (field) { return ['th', field]; })], dale.do (DATA, function (product) { var matches = (! FILTER || FILTER.length === 0) || dale.stop (product.categories, true, function (category) { return FILTER.indexOf (category) !== -1; }); return matches === false ? [] : ['tr', { id: product.id, class: product.onSale ? 'onsale' : undefined }, dale.do (printableFields, function (field) { return ['td', product [field]]; })]; }) ]]; }

Наясно съм, че това не е ясен пример, но представлява доста опростен изглед на 4-те основни постоянни функции за съхранение, известни също като ЖЕСТКО . Всяко нетривиално уеб приложение ще има изгледи, които са по-сложни от това.

Сега нека видим какво прави този код. Първо дефинирайте функция, drawTable да съдържа логическото представяне на чертежа на продуктовата таблица. Тази функция получава DATA и FILTER като параметри, затова може да се използва от различни набори от данни и филтри. drawTable Той има двойна роля, като е частичен и помощник.

var drawTable = function (DATA, FILTER) {

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

var printableFields = ['description', 'price', 'categories'];

След това класифицираме DATA според цената на техните продукти. Имайте предвид, че някои различни и по-сложни критерии за класификация биха били по-лесни за изпълнение, тъй като разполагаме с целия програмен език.

DATA.sort (function (a, b) {return a.price - b.price});

Тук връщаме буквален обект; масив, който съдържа „таблица“ като първи елемент и съдържанието му като втори. Това е dsDSL представяне на

искаме да творим.

return ['table', [

Сега създаваме ред със заглавията на таблицата. За да създадем вашето съдържание, ние използваме продължавай което е функция като Array.map , но това работи и за обекти. Нека да повторим printableFields и генерирайте заглавки на таблици за всеки от тях:

['tr', dale.do (printableFields, function (field) { return ['th', field]; })],

Можете да видите, че току-що внедрихме итерация, работната сила за генериране на HTML и не беше необходимо да имаме DLS компилации; просто се нуждаем от функция за итерация през структура на данни и връщане на dsDSL. Подобна естествена или внедрена от потребителя функция би имала същия ефект.

Сега трябва да прегледате продуктите, съдържащи се в DATA.

dale.do (DATA, function (product) {

Проверяваме дали този продукт е отхвърлен от FILTER. Ако FILTER е празно, можем да отпечатаме продукта. Ако FILTER не е празно, ще прегледаме категориите продукти, докато намерим такъв, който е вътре FILTER Правим това, използвайки dale.stop .

var matches = (! FILTER || FILTER.length === 0) || dale.stop (product.categories, true, function (category) { return FILTER.indexOf (category) !== -1; });

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

Ако coincidencia е falsa, връща се празен масив (така че не отпечатваме този продукт). В противен случай a

със съответния идентификатор и клас, точно както итерираме през printableFields за да отпечатате полетата несъмнено.

return matches === false ? [] : ['tr', { id: product.id, class: product.onSale ? 'onsale' : undefined }, dale.do (printableFields, function (field) { return ['td', product [field]];

Разбира се, ние затваряме всичко, което отваряме. Синтаксисът е забавен, нали?

})]; }) ]]; }

Сега, как да включим тази таблица в по-широк контекст? Пишем функция, наречена drawAll което ще извика всички функции, които генерират изгледите. Освен drawTable, бихме могли да имаме и drawHeader, drawFooter и други сравними функции, всички тези dsDSL ще се върнат .

var drawAll = function () { return generate ([ drawHeader (), drawTable (DATA, FILTER), drawFooter () ]); }

Ако не ви харесва начина, по който изглежда горният код, нищо, което казвам, няма да ви убеди. Това е dsDSL в най-добрия случай . На този етап можете да спрете да четете статията (и също така да оставите лош коментар, защото сте спечелили правото да го направите, ако сте стигнали до този момент!). Но сериозно, ако горният код не изглежда изискан, нищо в тази статия няма.

За тези, които все още ме следват, бих искал да се върна към началното изявление на този раздел, което е какво dsDSL има предимствата както на високо, така и на ниско ниво :

  • The предимство на ниско ниво става въпрос за писане на кодове, когато пожелаем, да се отървем от DSL тесната риза.

  • The предимство на високо ниво е да използваме литерали, които представляват това, което искаме да декларираме, и да оставим функциите на инструмента да го преобразуват в желаното крайно състояние (в този случай последователност с HTML).

Но как това се различава от чисто императивния код? Мисля, че елегантността на подхода dsDSL се свежда до факта, че код, написан по този начин, се състои предимно от изрази, а не от декларации . За да бъдем по-точни, всеки код, който използва dsDSL, на практика се състои от:

  • Литерали, които се отразяват на по-ниско ниво структури.
  • Извиквания на функции или ламбда в рамките на тези буквални структури че връщат структури от същия клас.

Кодът, състоящ се предимно от изрази, който капсулира повечето декларации във функциите, е изключително кратък, тъй като всички повтарящи се модели могат лесно да бъдат абстрахирани. Можете да пишете произволен код, стига този код да връща литерал, който отговаря на много специфична непроизволна форма.

Друга характеристика на dsDSL (която засега не може да бъде изследвана много) е възможността да се използват типове, за да се увеличи привлекателността и сочността на литералните структури. В следваща статия ще подчертая този въпрос.

Може ли да се създаде dsDSL без JavaScript, Единственият истински език? Да, мисля, че е възможно, стига езикът да поддържа:

  • Литерали за: масиви, обекти (асоциативни масиви), извиквания на функции и ламбда.
  • Откриване на типа изпълнение
  • Динамични видове връщане и полиморфизъм

Мисля, че това означава, че dsDSL са устойчиви в съвременния динамичен език (т.е.: Ruby, Python, Perl, PHP), но вероятно не в C или Java.

Първо вървете, после се плъзгайте: Как да разгърнем високото от ниското

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

  1. Вземете два или четири проблема, които представляват екземпляри на проблем с домейн. Тези проблеми трябва да са реални. Показването на високото ниво от ниското е индукционен проблем, поради което се нуждаете от реални данни, за да можете да получите представително решение.
  2. Решете проблемите без инструмент по възможно най-бързия начин.
  3. Отделете малко време, за да разгледате вашите решения и да забележите общите модели, които имат.
  4. Намерете моделите на представяне (високо ниво).
  5. Намерете моделите на генериране (ниско ниво).
  6. Решете същите проблеми с носа си на високо ниво и проверете дали решенията са правилни.
  7. Ако установите, че можете лесно да представите всички проблеми с вашите модели за изобразяване и моделите за изграждане за всеки от тези екземпляри произвеждат правилните имплементации, добре е да започнете. Ако не, върнете се към чертожната дъска.
  8. Ако се появят нови проблеми, разрешете ги с инструмента и ги коригирайте съответно.
  9. Инструментът трябва асимптотично да се сближи до крайно състояние, независимо колко проблеми решава. С други думи, сложността на даден инструмент трябва да остане постоянна, а не да нараства с броя на проблемите, които той решава.

Какво по дяволите са модели на изобразяване Y. модели на генериране ? Добре, че попитахте. Представителните модели са моделите, при които трябва да можете да изразите проблем, който принадлежи на домейн, който се отнася до вашия инструмент. Това е азбука от структури, която ви позволява да напишете всеки шаблон, който искате да изразите в приложимия домейн. На DSL това биха били производствените правила. Сега да се върнем към нашия dsDSL, за да генерираме HTML.

Скромният HTML таг е добър пример за модели на изобразяване. Сега нека разгледаме по-отблизо тези основни модели.

Скромният HTML таг е добър пример за модели на изобразяване. Сега нека разгледаме по-отблизо тези основни модели. Tweet

Моделите на изобразяване за HTML са както следва:

  • Етикет: ['TAG']
  • Етикет с атрибути: ['TAG', {attribute1: value1, attribute2: value2, ...}]
  • Етикет със съдържание: ['TAG', 'CONTENTS']
  • Етикет с атрибути и съдържание: ['TAG', {attribute1: value1, ...}, 'CONTENTS']
  • Етикет с друг етикет вътре: ['TAG1', ['TAG2', ...]]
  • Група маркери (самостоятелно или в рамките на други тагове): [['TAG1', ...], ['TAG2', ...]]
  • В зависимост от определено условие поставете етикет или не: condition ? ['TAG', ...] : [] / В зависимост от определено условие, поставете атрибут или не: ['TAG', {class: condition ? 'someClass': undefined}, ...]

Тези екземпляри могат да бъдат представени с dsDSL нотация, която определихме в предишния раздел. И това е всичко, от което се нуждаете, за да изобразите каквото и да е HTML, от което се нуждаете. По-сложни модели, като например условна итерация през обект за генериране на таблица, могат да бъдат внедрени с функции, които връщат споменатите по-горе модели на изобразяване и тези шаблони се преобразуват директно в HTML тагове.

Ако моделите на изобразяване са структурите, използвани за изразяване на това, което искате, моделите на изобразяване са структурите, които вашият инструмент ще използва, за да преобразува образците на изобразяване в структури на ниско ниво. За HTML това са:

  • Проверете въведеното (всъщност това е универсален модел на генериране).
  • Отваряне и затваряне на маркери (но празни етикети като, които се затварят сами)
  • Задава атрибути и съдържание, избягвайки специални символи (но не и съдържанието на етикети и)

Вярвате или не, това са моделите, които трябва да създадете, за да покажете dsDSL слой, който генерира HTML: Подобни модели могат да бъдат намерени за генериране на CSS. Всъщност лит прави и двете в ~ 250 реда код.

за какво е добър ruby ​​on rails

И накрая, какво имам предвид под ' разходка, след това плъзнете ? Когато попаднем на проблем с домейн, искаме да използваме инструмент, който ни спасява от ужасните подробности за този домейн. С други думи, ние искаме да се отървем от ниското ниво, без никой да забележи, и колкото по-бързо, толкова по-добре. Подходът „ходи, после се плъзгай“ предлага точно обратното на това: останете по-дълго на ниското ниво. Приятете се към техните странности и разберете кои са от съществено значение и кои могат да бъдат избегнати, когато възникнат реални, разнообразни и полезни проблеми.

След като вървите известно време на ниско ниво и след това решавате полезни проблеми, тогава ще имате по-дълбоко разбиране за неговото майсторство. Моделите на представяне и генериране ще се появят естествено; Те произтичат от естеството на проблемите, които се опитват да решат. След това можете да напишете кода, който ще ги използва. Ако работят, ще можете да се плъзнете през проблемите, където наскоро ви се е налагало да ходите. Плъзгането означава много неща; това предполага скорост, прецизност и липса на триене. Може би това качество се усеща повече, когато решавате проблеми с този инструмент, чувствате ли, че навлизате в проблема, или смятате, че се изплъзвате през него?

Може би най-важното при инструмента за внедряване не е фактът, че ни освобождава от необходимостта да се справяме с ниския клас. По-скоро, като улавя емпирични модели на повторение на ниско ниво, един добър инструмент на високо ниво ни позволява да разберем напълно приложимостта на домейна.

Инструментът за внедряване не само ще реши проблем - той също така ще ви помогне да разберете структурата на проблема.

Така че не бягайте от ценен проблем. Първо преминете през него и след това се плъзнете през него.

Свързани:Въведение в едновременното програмиране: Ръководство за начинаещи

Как ПМ ​​могат да бъдат готови за роботизирана автоматизация на процесите

Тенденции

Как ПМ ​​могат да бъдат готови за роботизирана автоматизация на процесите
Нова уеб поръчка: Общ преглед на дизайна, който е първи за съдържанието

Нова уеб поръчка: Общ преглед на дизайна, който е първи за съдържанието

Процес На Проектиране

Популярни Публикации
Първи стъпки с модули и модулна разработка отпред
Първи стъпки с модули и модулна разработка отпред
Най-добри практики за уеб оформление: Анализирани са 12 вечни модела на потребителския интерфейс
Най-добри практики за уеб оформление: Анализирани са 12 вечни модела на потребителския интерфейс
H-1B: Пътешествие на разработчика на iOS от Хондурас до Силициевата долина
H-1B: Пътешествие на разработчика на iOS от Хондурас до Силициевата долина
Agile UX: Как да включите UX и продуктовия дизайн в Agile
Agile UX: Как да включите UX и продуктовия дизайн в Agile
Съвети за привличане, управление и задържане на разработчици на софтуер
Съвети за привличане, управление и задържане на разработчици на софтуер
 
Въведение в търговията с дълбоко обучение в хедж фондове
Въведение в търговията с дълбоко обучение в хедж фондове
Magento 2: Ревизия или революция?
Magento 2: Ревизия или революция?
Кутия с инструменти на Forecaster’s: Как да извършите симулации на Монте Карло
Кутия с инструменти на Forecaster’s: Как да извършите симулации на Монте Карло
Ръководител на растежа
Ръководител на растежа
Вицепрезидент по комуникациите
Вицепрезидент по комуникациите
Популярни Публикации
  • системи за валутна търговия, които действително работят
  • Wells fargo неетични бизнес практики
  • как работи носимата технология
  • Glas Steagall Act отменя последствия
  • файловите разширения java, c и cpp обикновено се използват за кое от следните?
  • как да хакна номера на кредитни карти 2016
Категории
  • Kpi И Анализ
  • Инвеститори И Финансиране
  • Други
  • Финансови Процеси
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt