Konkatenativt programmeringssprog

Den aktuelle version af siden er endnu ikke blevet gennemgået af erfarne bidragydere og kan afvige væsentligt fra den version , der blev gennemgået den 2. januar 2016; checks kræver 11 redigeringer .

Et sammenkædet programmeringssprog  er et programmeringssprog baseret på det faktum, at sammenkædningen af ​​to stykker kode udtrykker deres sammensætning . I et sådant sprog er den implicitte specifikation af funktionsargumenter meget brugt (se meningsløs programmering ), nye funktioner defineres som sammensætning af funktioner, og sammenkædning bruges i stedet for applikation [1] . Denne tilgang er i modsætning til applikativ programmering .

Mange sammenkædede sprog bruger postfix-notation og en stak til at gemme argumenter og returnere værdier af operationer, så sammenkædede sprog betyder normalt staksprog. Sammenkædningssprog kan dog bygges på andre principper, så begreberne stabelsprog og sammenkædningssprog er ikke synonyme.

Sammenkædningssprog er enkle, effektive og nemme at implementere, så de mest populære sprog af denne type bruges i programmerbare regnemaskiner og til indlejring i små mikroprocessorsystemer. For eksempel bruges det sammenkædede sprog RPL i Hewlett-Packard HP-28 og HP-48 programmerbare lommeregnere . Forth - programmeringssproget er blevet implementeret på mange processorer med meget begrænsede computeregenskaber [2] , for eksempel blev det brugt på Jupiter ACE -computeren med en basis-RAM på kun 1 KB. Men på grund af deres usædvanlige og vanskeligheder med at læse programmers kildekode, er sammenkædningssprog forblevet niche.

Det mest almindelige sammenkædningssprog er PostScript -sidebeskrivelsessproget , hvoraf en begrænset delmængde bruges i PDF . Dens tolk er indbygget i mange højtydende printere.

Definition

Et programmeringssprog kaldes konkatenativt, hvis det opfylder følgende krav:

I et sammenkædet sprog er hvert udtryk en funktion. Der er ingen speciel applikationsoperation, for at anvende funktionen på argumenterne, er det nok at sætte funktionsnavnet ved siden af ​​argumenterne, det vil sige at udføre tekst "limning" (sammenkædning). Nye funktioner er også defineret ved sammenkædning, som blot er en sekvens af andre funktionsnavne.

Lad funktioner fooaf to argumenter og baret argument gives. For at anvende foopå argumenter, i præfiksnotation , er det nok at komponere et udtryk som dette:

foo 4 5

Anvend nu funktionen bartil resultatet af funktionen foo:

bar foo 4 5

Lad os endelig definere en funktion bazsom en sammenkædning af tre funktioner:

define baz
    bar foo 4
end-define

Udtrykket baz 8svarer til udtrykket bar foo 4 8. Det vil sige, at navnet på enhver funktion kan erstattes med teksten i dens definition, og det korrekte udtryk kan opnås. Dette enkle princip definerer de særlige forhold ved sammenkædede sprog, deres fordele og ulemper.

Funktioner

For at sammenkædningen af ​​kodefragmenter altid skal udtrykke deres sammensætning, skal sproget kun have funktioner af ét argument. [3] I dette tilfælde kan du nægte at specificere argumentet eksplicit, så ved at bruge et ensartet præfiks eller postfix-notation kan du oprette et programmeringssprog, hvor sammenkædningen af ​​kodefragmenter udtrykker deres sammensætning, det vil sige et sammenkædningssprog.

En enkel og effektiv måde at implementere denne tilgang på er at bruge en stak . Funktioner tager argumenter fra stakken og skubber resultatet over på stakken. Derfor kan vi sige, at i sammenhængende stak programmeringssprog tager funktioner ét argument - stakkens tilstand og returnerer en ny tilstand af stakken. [4] Disse sprog bruger normalt postfix-notation , fordi stakken fungerer i LIFO .

Der er andre måder. For eksempel tager en funktion programmets tekst og returnerer den med nogle ændringer, der afspejler dets arbejde. Et meget enkelt og fleksibelt homoikonisk sprog kan bygges på dette princip. [5] Det er muligt at bygge et sprog omkring princippet i UNIX-pipelinen : hver funktion tager en streng og returnerer en ny streng efter behandling. [6] I modsætning til det tidligere princip indeholder teksten, der sendes til funktionen, kun argumenter, ikke hele programmet. Disse metoder kan arbejde med både præfiks- og postfix-notation.

I stedet for en stak kan andre datastrukturer bruges, såsom en eller en deque (deque) [7] .

Ideen med et sammenkædet sprog er denne: alle udtryk er funktioner, der tager noget af den samme datastruktur og returnerer dens nye tilstand. Denne datastruktur (stak, deque, kø, tekststreng osv.) spiller rollen som lim til at "lime" funktioner ind i et program, den gemmer programmets tilstand. Denne tilgang definerer fordele og ulemper ved sammenkædede sprog.

Fordele:

Fejl:

Implementeringer

Det første sammenkædningssprog på højt niveau var Forth , udviklet af Charles Moore i slutningen af ​​1960'erne og begyndelsen af ​​1970'erne. Den brugte en typeløs stak og var nem at implementere og yderst effektiv, hvilket gjorde det muligt at implementere compilere selv med ekstremt begrænsede computerressourcer. Frem påvirkede de efterfølgende sammenkædede sprog betydeligt.

Foredragsholder og programmør Manfred von Thun ved La Trobe University , påvirket af John Backus ' berømte foredrag "Kan programmering befries fra von Neumanns stil?" udviklede Joy stack programmeringssproget og lagde det teoretiske grundlag for sammenhængende programmering. Det var Joy-sproget, der først blev kaldt sammenkædning.

Påvirket af Forth og Joy skabte Slava Pestov programmeringssproget Factor stack i 2003 . Det er placeret som et "praktisk stack-programmeringssprog". Senere blev de stack-sammenkædede sprog Cat og Kitten udviklet , som er kendetegnet ved statisk skrivning . Et andet moderne sammenkædningssprog, min , har en minimalistisk syntaks og en meget kompakt implementering (ca. 1 megabyte) og bruges i HastySite- webstedsgeneratoren .

Af de specialiserede stack-sprog er de mest kendte PostScript , som bruges til at beskrive sider og udskrive dem, samt RPL , programmeringssproget for HP-28 og HP-48 lommeregnere .

Arbejde med stakken

De fleste sammenkædede programmeringssprog bruger stakken til at sende argumenter. Dette skyldes den lette implementering og stakkens egenskaber, som er praktisk at bruge med postfix-notation. Overvej at arbejde med stakken ved at bruge sproget Forth som eksempel.

I Forth består et program af ord adskilt af mellemrum. Hvis ordet er et tal, skubbes det op på toppen af ​​stakken. Hvis ord er navnet på en funktion, så kaldes den funktion (i Forth terminologi kaldes funktioner ord). Den tager argumenter fra stakken og skubber resultatet over på stakken. Overvej det enkleste program, som består af fire ord:

3 4 + .

De første to ord er tal, så de skubbes på stakken. Så kaldes funktionen +, som tager to tal fra stakken, tilføjer dem og skubber resultatet over på stakken. Så kaldes funktionen ., som viser tallet fra stakken. Således går argumenterne forud for funktionen, hvorfor denne notation kaldes postfix.

Vanskeligheder og overvindelse af dem

Konkatenative sprog til generelle formål har ikke vundet betydelig popularitet. Dette skyldes deres specifikke fordele og ulemper, som er en konsekvens af det grundlæggende princip: alle funktioner tager ét argument og returnerer én værdi. Når præcis dette er påkrævet, er der ingen problemer, og sammenkædningssprog giver dig mulighed for at skrive meget enkle, kortfattede og klare programmer. Antag, at et sammenkædet sprog med postfix-notation har følgende funktioner, der accepterer og returnerer tekststrenge:

input - returnerer teksten indtastet af brugeren print - viser tekst på skærmen upcase - Ændrer små bogstaver til store bogstaver i en streng first_word - returnerer det første ord i en streng (klipper strengen til det første mellemrum efter det første ord)

Lad os bruge dem til at skrive et program, der viser brugerens navn med store bogstaver:

input first_word upcase print

Der opstår vanskeligheder, når du skal bruge funktioner med forskelligt antal argumenter. I et stack-sprog skal du placere argumenterne i en bestemt rækkefølge, og ofte skal du bytte rundt på dem. Hvis et argument bruges flere gange i en funktion, skal det også duplikeres. Dette fører til svært forståelige udtryk. For eksempel funktionen

f x y z = y² + x² − |y|

i staksproget skrives som følger:

f = drop dup dup × swap abs rot3 dup × swap − +

Brug af variabler

Variabler bruges eksplicit i moderne sammenkædede sprog som Kitten og min for at overvinde disse vanskeligheder. På killingsprog er variabler erklæret sådan:

->x; // variabel x vil få sin værdi fra stakken 5 -> y; // y = 5 1 2 3 -> xyz; // x = 1; y=2; z = 3

Overvej funktionen ved at kvadrere et tal. Traditionelt for stabelsprog i Kitten er det skrevet som følger: [8]

define square (Int32 -> Int32):
    dup (*)

Og så kan det omskrives ved hjælp af en variabel:

define square (Int32 -> Int32):
    -> x;
    x * x

I dette enkleste eksempel giver dette ingen særlig mening. Men hvis et argument eller argumenter bruges mange gange i en funktion, forenkler brugen af ​​variabler meget at skrive programmet og læse kildekoden. Et fragment af programkoden, der viser sangen 99 flasker øl :

definer bottles_of_beer (Int32 -> +IO): ->x; xvers hvis (x > 1): (x - 1) flasker_øl

I programmeringssproget min bruges symboler på samme måde:

x define  ; символ x получит значение из стека
:x        ; сокращённая запись
8 :x      ; x = 8

Overvej for eksempel et min -program , der returnerer sandt, hvis en fil er større end 1 megabyte og for nylig er blevet ændret:

dup dup
"\.zip$" match
swap fsize 1000000 > and
swap mtime now 3600 - >

Ved at bruge symbolet kan du undgå duplikering og omarrangering af stakelementer og forbedre kodens læsbarhed markant:

:filepath
filepath "\.zip$" match
filepath fsize 1000000 >
filepath mtime now 3600 - >
and and

Brugen af ​​variable bringer sammenkædningssprog tættere på anvendelige, men der er stadig grundlæggende forskelle mellem dem. I sammenkædede sprog har programmøren valget mellem at bruge stakken (eller en lignende mekanisme) eller deklarere variabler. Derudover er mekanismen til at arbejde med variabler ret gennemsigtig og overskuelig. Dette giver fleksibilitet og mulighed for en effektiv og relativt enkel implementering.

Se også

Noter

  1. John Purdy. Hvorfor konkatenativ programmering er  vigtig . Hentet 23. januar 2018. Arkiveret fra originalen 24. januar 2018.
  2. Oleg Paramonov. Aliens: The Strange Architecture of Alien Computers . Hentet 25. januar 2018. Arkiveret fra originalen 26. januar 2018.
  3. Xah Lee. Hvad er punktfri programmering? (punktfri funktionssyntaks  ) . Hentet 25. januar 2018. Arkiveret fra originalen 26. januar 2018.
  4. potomushto. Stablede programmeringssprog . Hentet 25. januar 2018. Arkiveret fra originalen 26. januar 2018.
  5. Sparist. Om : Hovedside  . Hentet 25. januar 2018. Arkiveret fra originalen 10. september 2017.
  6. Xah Lee. Unix Pipe som funktionelt  sprog . Hentet 25. januar 2018. Arkiveret fra originalen 26. januar 2018.
  7. Deque  . _ Hentet 25. januar 2018. Arkiveret fra originalen 26. januar 2018.
  8. John Purdy. Hvorfor konkatenativ programmering er  vigtig . Hentet 25. januar 2018. Arkiveret fra originalen 25. januar 2018.

Links