Jezici specifični za domen
Sadržaj
Problem i motivacija
Šta je jezik?
- Komunikacija misli i osećanja sistemom znakova kao što su zvuci, gestovi ili pisani simboli1.
- Sistem znakova, simbola, gestova i pravila koji se koriste u komunikaciji2.
Šta je softverski jezik?
- Jezik korišćen u komunikaciji čovek-računar ili računar-računar.
- U varijanti čovek-računar težimo da jezik bude lak za razumevanje od strane čoveka ali ipak da može da se procesira na efikasan način od strane računara.
-
U kontekstu razvoj softvera dve su uloge jezika:
- preskriptivna - za opis budućih sistema
- deskriptivna - za opis postojećih sistema
Šta domen?
- Sfera delovanja, interesa ili funkcije1.
- Oblast znanja, uticaja, ili delovanja2.
- Da bi se domensko znanje moglo procesirati i da bi mogli komunicirati u određenom domenu korisno je definisati ontologiju domena koja opisuje koncepte domena i njihove međusobne veze.
- Primer domena: osiguranje, zdravstvo, finansije, saobraćaj…
- Domeni mogu sadržati poddomene. Na primer, ako je posmatrani domen problema osiguranje, poddomeni mogu biti životno osiguranje, osiguranje vozila, osiguranje nekretnina i sl.
Jezici specifični za domen - JSD (Domain-Specific Languages - DSL)
- Jezici specifični za domen (JSD, eng. Domain-Specific Languages - DSL) su jezici prilagođeni i ograničeni na određeni domen problema.
- Za razliku od jezika opšte namene (JON, eng. General Purpose Language - GPL), nude povećanje ekspresivnosti kroz upotrebu koncepata i notacija prilagođenih domenu problema i domenskim ekspertima.
- Nazivaju se još i mali jezici (eng. little languages).
- Uspešan JSD je fokusiran na uzak, dobro definisan domen i pokriva ga na odgovarajući način.
- Domen često ima svoj jezik korišćen od strane domenskih eksperata iako ne postoji njegova implementacija na računaru.
Primeri
SQL
SELECT player, stadium
FROM game JOIN goal ON (id=matchid)
JPA mapiranje
@Entity
@Table(name="COURSES")
public class Course {
private long courseId;
private String courseName;
public Course() {
}
public Course(String courseName) {
this.courseName = courseName;
}
@Id
@GeneratedValue
@Column(name="COURSE_ID")
public long getCourseId() {
return this.courseId;
}
}
Build jezici (Ant/Maven/Gradle)

Poslovni procesi - BPMN

OrgMode
Beleške, kreiranje sadržaja, agenda, pismeno programiranje (literate programming).
** PROJ
*** TODO Pregledati prijavu greške #173
SCHEDULED: <2022-12-14 Wed>
1. [x] Neko parče koda:
#+begin_src rust
fn main() {
// Statements here are executed when the compiled binary is called
// Print text to the console
println!("Hello World!");
}
#+end_src
#+RESULTS:
: Hello World!
2. [ ] Neka druga zabeleška...
*** WAIT Predati projektni izveštaj
| Aktivnost | Završeno | Problemi |
|----------------+----------+------------------------|
| Prva aktivnost | 30% | Nema |
| Druga aktinost | 25% | Problemi u snabdevanju |
Scratch
Učenje programiranja za decu.
Inform
Inform je jezik za kreiranje interaktivne fikcije (tekstualnih avantura) baziran na prirodnom jeziku.
"Cactus Will Outlive Us All"
Death Valley is a room. Luckless Luke and Dead-Eye Pete are men in the Valley.
A cactus is in the Valley. Persuasion rule: persuasion succeeds.
A person has an action called death knell. The death knell of Luckless Luke is pulling the cactus.
The death knell of Dead-Eye Pete is Luke trying dropping the cactus.
Before an actor doing something:
repeat with the victim running through people in the location:
let the DK be the death knell of the victim;
if the DK is not waiting and the current action is the DK:
say "It looks as if [the DK] was the death knell for [the victim], who looks startled,
then nonexistent.";
now the victim is nowhere.
ChucK
Jezik za kreiranje muzike i sintezu zvuka u realnom vremenu.
// this synchronizes to period
.5::second => dur T;
T - (now % T) => now;
// construct the patch
SndBuf buf => Gain g => dac;
// read in the file
"kick.wav" => buf.read;
// set the gain
.5 => g.gain;
// time loop
while( true )
{
// set the play position to beginning
0 => buf.pos;
// randomize gain a bit
Math.random2f(.8,.9) => buf.gain;
// advance time
1::T => now;
}
GritQL
GritQL je JSD za pretragu, linting i transformaciju koda.
`console.log($log)` => . where {
$log <: not within `try { $_ } catch { $_ }`
}
Colobot
- Colobot je edukativna real-time strategija.
- Igrač programira robote u virtuelnom okruženju JSD-om nalik na C++ i Javu.
Mobilne aplikacije

Ali i…

ili…

pa čak i…

Kada jezik smatramo JSD-om?
- Zavisi od toga šta nam je domen.
- Jezik može biti više ili manje prilagođen nekom domenu.
- U ekstremnom slučaju i opšti jezik kao što je Java možemo smatrati JSD-om ako nam je domen "razvoj softvera". Naravno, iako tačno u teorijskom smislu, u praktičnom gubimo sve prednosti JSD.
- Dobar JSD pokriva uzak, dobro definisan domen (domen problema). Koristi samo koncepte ciljnog domena, ograničen je na dati domen i samim tim je iskazivanje rešenja jezgrovitije i jasnije domenskim ekspertima.
- Čest je slučaj da jezik nastane kao JSD ali se vremenom proširi do te mere da ga možemo smatrati JON.
Prednosti
Uticaj na produktivnost
- Pojedine studije pokazuju da povećanje produktivnosti ide i do 1000%1.
- Šta je osnovni razlog za povećanje produktivnosti?
Problem mentalnog mapiranja
Rešenje upotrebom JSD
Zašto JSD?
- JSD su koncizniji od jezika opšte namene što omogućava korisnicima da jasnije iskažu svoju nameru.
- JSD sintaksa, bilo tekstualna ili grafička, može se prilagoditi i približiti domenskim ekspertima.
- Koncepti korišćeni u JSD su koncepti problemskog (poslovnog) domena što pod određenim uslovima omogućava da domenski eksperti direktno koriste JSD bez posredovanja programera.
- Upotrebom koncepata problemskog domena izbegava se ručno mapiranje na koncepte ciljne implementacione platforme. Taj posao se obavlja automatski upotrebom JSD prevodioca (kompajlera ili generatora koda).
- Iskazivanje rešenja konceptima nezavisnim od korišćene tehnologije rezultuje dužim životnim vekom aplikacije.
- Samodokumentujući jezički iskazi.
Uticaj na kvalitet softvera
- Korišćenje koncepata domena problema dovodi do smanjenja broja linija koda (u terminologiji tekstualnih notacija), što ima pozitivan uticaj na brzinu razvoja i jednostavnost odžavanja.
- Smanjenje broja linija koda ide i do 50 puta u pojedinim domenima primene. Gustina softverskih grešaka (broj softverskih grešaka na hiljadu linija koda) ne zavisi značajno od jezika koji se koristi.
- Iz toga se može zaključiti da JSD kroz smanjenje broja linija koda posredno utiču na smanjenje apsolutnog broja softverskih grešaka što povećava kvalitet softverskog proizvoda i smanjuje cenu održavanja.
- Prevođenje koda na ciljnu platformu (kompajliranje) će rezultovati konzistentnim kodom.
Uticaj na evoluciju aplikacije
- Iskazivanje rešenja konceptima nezavisnim od korišćene tehnologije rezultuje dužim životnim vekom aplikacije.
- Nije potrebno menjati jezičke iskaze (programe/modele) kada dođe do promene tehnologije. Potrebno je ažurirati generator koda.
Arhitekture
Arhitektura bazirana na prevodiocima
Arhitektura bazirana na interpreterima
Gradivni elementi
Gradivni elementi JSD
Kao i svaki softverski jezik i JSD se sastoji od:
- Apstraktne sintakse
- Jedne ili više konkretnih sintaksi
- Semantike
Apstraktna sintaksa
- Određuje pravila validnosti iskaza sa stanovišta njegove strukture.
- Definiše koncepte domena, njihove osobine i međusobne relacije
- Jezici za definisanje apstraktnih sintaksi jezika se u domenu modelovanja nazivaju meta-meta-modelima1.
Primer - apstraktna sintaksa jezika za opis konačnih automata
Apstraktno sintaksno stablo
- Svaki iskaz na datom jeziku se može na apstraktan način opisati apstraktnim sintaksnim stablom (Abstract Syntax Tree).
- Konkretna sintaksa nije važna u tom slučaju (na primer, ako posmatramo program na Javi tada ključne reči nisu deo apstraktnog stabla).
Primer apstraktnog sintaksnog stabla
Konkretna sintaksa
- Da bi mogli da prikažemo iskaz na konkretan način potrebna nam je konkretna sintaksa.
- Konkretna sintaksa definiše izgled iskaza na nekom jeziku, odnosno u širem smislu definiše i načine interakcije korisnika sa jezičkim iskazima tj. predstavlja interfejs jezik-korisnik.
- Iako nam je dovoljna jedna konkretna sintaksa za jedan jezik, možemo ih imati više.
Konkretna sintaksa
Primer istog iskaza upotrebom dve različite konkretne sintakse
Semantika
- Definiše smisao jezičkih iskaza.
- Iako postoje i druge tehnike u praksi se najčešće semantika definiše prevođenjem (kompajliranjem tj. generisanjem koda) na jezik koji već ima definisanu semantiku putem prevodioca na niže jezike ili interpretera (npr. virtualne mašine).
- Najčešće su ciljni jezici na koje se JSD prevodi jezici opšte namene.
- Primer: generisanje Java programskog koda iz JSD jezičkog iskaza.
- Jezici se prevode na sve "niže" i "niže". Gde je kraj prevođenju? Mašinski jezik. Definisan u hardveru računara (procesoru).
Klasifikacija
Podela JSD prema vrsti konkretne sintakse
- Tekstualni
- Grafički
- Tabelarni
- Baziran na ekranskim formama
- …
- Hibridni - kombinacija više osnovnih
Tekstualne sintakse - prednosti i mane
- Programeri se osećaju "kod kuće".
- Mogu se koristiti regularni tekst editori.
- Serijalizovana forma je identična sa prezentacionom. se koristiti standardni sistemi za kontrolu verzija (Git, Mercurial, Subversion …).
- Podrška u alatima: bojenje koda, dopuna koda, pretraga, navigacija…
- Mana: Nije pogodna za opis i razumevanje strukture koja nije linearne prirode (grafovi, tabele itd.).
Grafičke sintakse - prednosti
- Razumevanje strukture. Podržano operacijama zoom, pan i sl.
- Često razumljivije domenskim ekspertima (najčešće je domenski jezik grafičke prirode).
- Intuitivniji i lakši za učenje - učenje kroz isprobavanje (paleta sa alatima i konceptima, onemogućavanje kreiranje nevalidnih konstrukcija itd.).
Grafičke sintakse - mane
- Još uvek složeniji za implementaciju i održavanje.
- Za serijalizaciju se koristi format koji se razlikuje od prezentacionog.
- Otežano ili potpuno nemoguće korišćenje standardnih alata za kontrolu verzija. Potrebno je razviti poseban VCS alat.
- Zahteva namenske editore.
Podela prema vrsti domena
Podela JSD prema načinu implementacije
- Interni - Nastali su na bazi već postojećih programskih jezika (najčešće JON).
- Eksterni - Izrađeni "on nule" definisanjem sintakse i implementacijom kompajlera koji prevodi programe pisane na ovom jeziku na neki drugi jezik (najčešće JON) ili se program direktno interpretira.
Interni JSD
- Bazirani na postojećem jeziku i alatima. Najčešće tekstualni.
- Koriste svu infrastrukturu jezika domaćina (editore, debagere, kompajlere/interpretere…).
- Brzi za implementaciju i laki za održavanje. Popularni u pojedinim zajednicama (Lisp, Ruby, Groovy, Scala…).
- Dobri kao ulaznica u svet DSL/DSM/MDE pristupa.
- Najčešće na pametan način koriste mogućnosti jezika (anonimne funkcije, meta-programiranje itd.).
- Ograničenja konkretne sintakse.
- Svaka namenska biblioteka može se smatrati internim JSD (API bazirani)…
- … ali konkretna sintaksa takvog jezika nije prilagođena domenu.
Eksterni JSD
- Izrađeni "on nule" - skuplji razvoj i održavanje.
- Puna kontrola konkretne sintakse - bolje prilagođavanje domenskim ekspertima.
- Editori i svi propratni alati takođe moraju da se prave "od nule"…
- …mada danas postoje alati koji nam taj posao olakšavaju.
Neki od poznatijih eksternih JSD
- SQL: tekstualni, domen - rad sa relacionim bazama podataka
- HTML: tekstualni, domen - definisanje sadržaja na vebu
- CSS: tekstualni, domen - stilizovanje sadržaja
- make: tekstualni, domen - izgradnja aplikacije (build)
- LaTeX: tekstualni, domen: kreiranje štampanih materijala (typesetting)
- Window Builder: GUI baziran, domen - izgradnja interfejsa
- R: tekstualni, domen - statistička obrada podataka
Primer: Interni JSD za definisanje email-a (JavaMail API)
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject("Greetings from Novi Sad");
message.setText("Enjoying my stay in Novi Sad! See you soon!");
Transport.send(message);
Primer: Hipotetički eksterni JSD za definisanje email-a
BEGIN myMail
FROM me@myself.com
TO myfriend@somewhere.org
SUBJECT Greetings from Novi Sad
Enjoying my stay in Novi Sad! See you soon!
END
SEND myMail
Primer
Interni JSD za definisanje grafički korisničkih interfejsa (Swing)
public DSLKurs() {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
contentPanel.setLayout(new FormLayout(new ColumnSpec[ {
FormFactory.RELATED_GAP_COLSPEC,
FormFactory.DEFAULT_COLSPEC,
FormFactory.RELATED_GAP_COLSPEC,
ColumnSpec.decode("default:grow"),},
new RowSpec[] {
FormFactory.RELATED_GAP_ROWSPEC,
FormFactory.DEFAULT_ROWSPEC,
FormFactory.RELATED_GAP_ROWSPEC,
FormFactory.DEFAULT_ROWSPEC,
FormFactory.RELATED_GAP_ROWSPEC,
FormFactory.DEFAULT_ROWSPEC,}));
....
Primer
Eksterni JSD za definisanje grafički korisničkih interfejsa (WindowBuilder)
Primer
Interni JSD za definisanje gramatike jezika (Arpeggio Python)
def number(): return _(r'\d*\.\d*|\d+')
def factor(): return Optional(["+","-"]), [number,
("(", expression, ")")]
def term(): return factor, ZeroOrMore(["*","/"], factor)
def expression(): return term, ZeroOrMore(["+", "-"], term)
def calc(): return OneOrMore(expression), EOF
Primer
Eksterni JSD za definisanje gramatike jezika (Arpeggio PEG)
number = r'\d*\.\d*|\d+'
factor = ("+" / "-")?
(number / "(" expression ")")
term = factor (( "*" / "/") factor)*
expression = term (("+" / "-") term)*
calc = expression+ EOF
Konkretna sintaksa je važna!!!
Neki jezici su pogodniji za kreiranje internih JSD
Jezici pogodni za kreiranje internih JSD
- Ruby
- Groovy
- Scala
- Lisp
- …
—
Primer internog JSD (Ruby Sinatra)
get '/dogs' do
# get a listing of all the dogs
end
get '/dog/:id' do
# just get one dog, you might find him like this:
@dog = Dog.find(params[:id])
# using the params convention, you specified in your route
end
post '/dog' do
# create a new dog listing
end
put '/dog/:id' do
# HTTP PUT request method to update an existing dog
end
delete '/dog/:id' do
# HTTP DELETE request method to remove a dog who's been sold!
end
Primer internog JSD (Groovy Gradle)
repositories {
mavenCentral()
}
dependencies {
groovy fileTree(dir: new File(gradle.gradleHomeDir, 'lib'),
includes: ['**/groovyall*.jar'])
compile gradleApi()
compile 'eu.appsatori:gradlefatjarplugin:0.1.3',
{
ext.optional = true
}
testCompile 'org.spockframework:spockcore:0.6groovy1.8'
}
Eksterni JSD omogućavaju potpuno prilagođavanje domenu.
Interni JSD za muzičku notaciju
Score k = new Score(Tonality.G_major);
Bar bar = new Bar(BarType.4_4);
t.addPause(Duration.1_4);
t.addNote(NoteType.A3, Duration.1_4);
t.addNote(NoteType.C2, Duration.1_4);
k.addBar(bar);
Eksterni JSD za muzičku notaciju
U eksternoj varijanti možemo u potpunosti prilagoditi konkretnu sintaksu domenskim ekspertima.

Lilypond note script
Ali se dešava da i u eksternoj varijanti JSD nije prilagođen domenskim ekspertima.

Kritike JSD
- Skup razvoj i održavanje jezika.
- Potreba za ekspertima u domenu razvoja jezika koji su istovremeno sposobni da analiziraju domen primene.
- Jezička "kakofonija" (Language Cacophony)1 i potreba da programeri poznaju veliki broj jezika (poseban jezik za svaki tehnički i/ili poslovni domen).
Low code/No Code platforme
Danas se platforme bazirane na JSD često brendiraju kao Low Code ili No Code platforme.
Jezičke radionice (Language Workbenches)
Jezičke radionice (Language Workbenches)
- Integrisana okruženja za razvoj, testiranje i evoluciju jezika i alata za njihovo efikasno korišćenje (editori, interpreteri, kompajleri i sl.). Koriste se kod paradigme razvoja orijentisane ka jezicima (Language Oriented Programming - LOP)1.
- Rešavaju problem brzine razvoja i lakoće održavanja JSD.
-
Primeri jezičkih radionica:
- Meta Programming System (MPS)
- Xtext
- Spoofax
Pristupi
-
Projekcione radionice - direktna izmena apstraktne reprezentacije kroz projekciju.
-
Bazirane na parserima - izmena se vrši posredno kroz tekst koji se parsira da bi se dobila apstraktna reprezentacija.
Projekcione radionice
-
Prednosti:
- Moguće višestruke konkretne sintakse (tekstualne, grafičke, tabelarne…) - bolje prilagođavanje konkretnom domenu.
- Sintakse se mogu "u letu" menjati.
- Kontrola validnosti izraza u vreme izmene modela.
-
Mane:
- Složenost alata.
- Format za perzistenciju nije u vezi sa konkretnim sintaksama koje korisnik koristi. Nemoguće je koristiti standardne sisteme za kontrolu verzija bazirane na tekstu.
- Moraju se razviti namenski generički editori za svaku klasu konkretnih sintaksi.
Radionice bazirane na parserima
-
Prednosti:
- Jednostavnije za izradu i održavanje.
- Teorija parsiranja dobro ustanovljena. Veliki broj biblioteka za parsiranje.
- Moguće koristiti obične tekstualne editore.
- Moguće koristiti standardne sisteme za kontrolu verzija (npr. git, subversion).
- Jednostavno kopiranje i lepljenje (eng. copy/paste).
-
Mane:
- Moguća samo tekstualna sintaksa -> ograničeno prilagođavanje domenu.
- Provera validnosti se odlaže do faze parsiranja.
Meta Programming System (MPS)
- JetBrains - http://www.jetbrains.com/mps/
- Projekciona jezička radionica - editori manipulišu direktno apstraktnom reprezentacijom (apstraktnim sintaksnim stablom). Čak i u slučaju tekstualnih notacija.
- Podrška za različite konkretne sintakse (notacije): tabelarne, tekstualne, bazirani na ćelijama, grafičke.
- Podrška za kontrolu verzija.
Meta Programming System - karakterističan izgled
Xtext
- Nastao kao deo projekta slobodnog softvera - openArchitectureWare.
- Iza razvoja u najvećoj meri stoji nemačka firma Itemis.
- Postao deo Eclipse projekta.
- Tekstualne sintakse. EBNF-like gramatika.
- Upotreba ECore meta-metamodela1. Meta-model se generiše iz gramatike a može da koristi i već postojeći meta-model.
- Generisanje Eclipse editora sa podrškom za bojenje sintakse, navigaciju, outline pogled itd.
- Xtext bazirani JSD se duboko integriše u Eclipse okruženje i teško je uočiti razliku sa podrškom za bilo koji drugi jezik sa Eclipse podrškom (npr. Java).
Xtext - Little tortoise jezik

Xtext - Little tortoise gramatika

Xtext - primeri
Za dokumentaciju sa primerom izgradnje 7 različitih jezika pogledati http://www.eclipse.org/Xtext/7languagesDoc.html
Spoofax
- Kao i Xtext baziran na parsiranju i tekstualnim sintaksama. Kreira punu podršku za jezik u vidu Eclipse priključaka.
- Istraživački projekat na TU Delft u Holandiji.
- Gramatika jezika se definiše meta-jezikom SDF (Syntax Definition Formalism).
- Parser koristi SGLR algoritam (Scanerless GLR) i omogućava parsiranje punog skupa kontekstno slobodnih gramatika. U slučaju neodređenosti parser vraća šumu parsiranja (parse forest) dok u slučaju determinističke gramatike vraća uvek stablo parsiranja (parse tree).
- Za tranformaciju programa i prepisivanje stabala koristi se JSD Stratego.
Spoofax - karakterističan izgled

Inženjerstvo softverskih jezika
- Software Language Engineering - SLE.
- Pravac i pogled na razvoj softverskih jezika koji pokušava da ujedini sve druge pravce koji u osnovi imaju razvoj i upotrebu softverskih jezika (MDE/MDA/DSM.., ontologije, grammarware, Language Oriented Programming…).
- Jedna od ideja je izjednačavanje modela i programa - kao jedinstven naziv predložen je mogram.*
Literatura
-
Osnovna
- Igor Dejanović, Jezici specifični za domen, Fakultet tehničkih nauka, Novi Sad, 2021. (dostupno u skriptarnici FTN-a)
-
Dodatna
- Meinte Boersma, Building User-Friendly DSLs, Manning, 2024.
-
- Völter, [[http://dslbook.org/][/DSL Engineering: Designing, Implementing and Using Domain-Specific
Languages/]]. 2013
-
- Kelly and J.-P. Tolvanen, /Domain-Specific Modeling: Enabling Full Code
Generation/. Wiley-IEEE Computer Society Pr, March 2008
- Federico Tomassetti, The complete guide to (external) Domain Specific Languages, February 2017.
- Alessio Stalla, Quick Domain-Specific Languages in Python with textX