Skip to Content

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)

./images/Ant-Maven-Gradle.png

Poslovni procesi - BPMN

./images/BPMN.png

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.

./images/scratch.png

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.

./images/colobot.png

Mobilne aplikacije

./images/MobilneAplikacije.png

Ali i…

./images/MusicNotation-External.png

ili…

./images/ChessNotation.png

pa čak i…

./images/saobracajni-znaci.jpg

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

./images/MentalnoMapiranje-1.svg

Rešenje upotrebom JSD

./images/MentalnoMapiranje-2.svg

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

./images/Arhitektura-kompajler.svg

Arhitektura bazirana na interpreterima

./images/Arhitektura-interpreter.svg

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

./images/StateMachine.svg

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

./images/RazliciteSintakse.png

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

./images/HorizontalniVertikalniDSL.svg

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)

./images/GUIDSL-External.png

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: ['**/groovy­all­*.jar'])
    compile gradleApi()
    compile 'eu.appsatori:gradle­fatjar­plugin:0.1.3',
    {
        ext.optional = true
    }
    testCompile 'org.spockframework:spock­core:0.6­groovy­1.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.

./images/MusicNotation-External.png

Lilypond note script

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

./images/Lilypond.png

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.

    ./images/projekcija.png
  • Bazirane na parserima - izmena se vrši posredno kroz tekst koji se parsira da bi se dobila apstraktna reprezentacija.

    ./images/parseri.png

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 - 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

./images/Spoofax-prikaz.png

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