• Opret dig
  • Glemt adgangskode

User account menu

  • Artikler
  • Forside
  • Forum
  • Nyheder
  • Log ind
Hjem
LinuxIN.dk

Snak med

Opret dig!

Af mich | 09.06.2012 02:42

Forth - brugerens eget sprog

Løst og fast
Der kom engang en bog på dansk med den titel. Ikke den bedste bog om emnet, men titlen er meget beskrivende.

På opfordring og i den gode tradition her på stedet, at skamrose sit yndlingssprog, vil jeg fortælle lidt om Forth og dets fortræffeligheder. Her glemmer vi for en stund, at man altid bør vælge det sprog, der egner sig bedst til opgaven.
Det er nu intet problem. En af Forths styrker og store fortrin er netop, at det er så let at udvide.
Man udvider blot sproget med de byggeklodser, der er nødvendige for at løse det foreliggende problem. Egentligt kan man ikke skrive nogen definitioner eller rutiner i Forth uden at udvide sproget. Derfor er Forth også blevet betegnet som et metasprog. Man bruger det til at opbygge et domænespecifikt sprog til at løse det aktuelle problem.

Forth er både kompileret og fortolket og derfor både hurtigt og interaktivt og meget let at debugge.

Her vil det nok lette forståelsen med en beskrivelse af sprogets opbygning.
Forth er til forskel fra de flest andre sprog stakbaseret, d.v.s. data overføres via en stak, og sproget er blevet beskrevet som semantisk i modsætning til de fleste andre sprog, der er syntaktiske. Forth har stort set ingen syntaks, ingen paranteser, kommaer eller semikoloner, der skal anbringes korrekt, men er i sin opbygning centreret om ordet.

Et ord i Forth svarer til en funktion eller en procedure i andre sprog, og det kaldes ved at skrive dets navn og trykke Enter. Først skal man lige sikre sig, at der er de rigtige parametre på stakken.

Navnet på et ord består af et antal tegn, i de fleste implementationer op til 31. Alle tegn kan anvendes undtagen mellemrum, der bruges til at adskille de enkelte ord.

Når man trykker Enter bliver de indtastede tegn skannet for ord afgrænset af mellemrum. Først blever det undersøgt, om det er gyldige tal med den valgte radix (mere om det senere). Hvis de er, bliver de lagt på stakken, hvis ikke, undersøges det, om det er et kendt ord. Hvis det er, udføres det, hvis ikke, tømmes stakken og der skrives en fejlmeddelelse.

Eksempel:
ok 3 5 + . cr 8
ok


3 og 5 er gyldige tal og lægges på stakken. + er et ord, der tager to tal fra stakken og adderer dem, og . betyder udskriv (print for de, der har glemt dette danske ords betydning).
cr betyder ny linie, og Forth skriver derfor ok på næste linie som tegn på, at systemet er klar til ny input.

Forth kan håndtere input og output i alle talsystemer fra 2 og op til vistnok 31. Det kan muligvis være implementationsafhængigt. Der er foruddefineret ord, der sætter talsystemet til henholdsvis Decimal, Hex og i nogle systemer også Binary. Er det ikke nok, kan man blot skrive
8 base !
Base er den variabel, der gemmer radix eller grundtallet for det aktuelle talsystem, og ! læses som store. Kodelinien svarer derfor til
base=8 eller base:=8 i C eller Pascal, men åbner for let og elegant indexering ind i f.eks. en buffer.

Forth er typeløst, og her gyser programmører opvokset med C eller andre typestærke sprog nok. Hvordan kan det gå godt? Men det går forbavsende godt. Hvis jeg vil lægge 5 til en pointer, er det mit problem, og hvis jeg vil behandle to halvdele af en double precision integer hver for sig, skal sproget ikke blande sig. Forth er designet til at være enkelt og hurtigt, og ud fra at det er programmørens ansvar, at programmet er korrekt og robust.
Forth kender kun en type, og det er stakken.

Det understøttes heldigvis af, at det er naturligt i Forth at skrive korte til utrakorte definitioner, da der er meget lille overhead ved at faktorisere, og stakken og de interaktive muligheder sammen med de korte definitioner, gør det let at teste og sikre sig, at ens byggeklodser virker korrekt.

Ulempen ved de manglende typer er, at man ikke kan nøjes med + for addition. Forth kan ikke se, hvad indholdet af stakken repræsenterer, så det er programmørens opgave at vælge mellem + for enkelt præcisions heltal, D+ for dobbelt præcision foruden tilsvarende udgaver af ord til at hente og gemme og manipulere stakken. Dertil kommer F+ for float eller real foruden de tilhørende hente, gemme og stakmanipulationsord. Float-ordsættet er ofte ikke inkluderet som standard, da utroligt meget kan klares med heltalsaritmetik, der er meget hurtigere. Er du f.eks. klar over at Pi kan repræsenteres som 355/113 med en fejl på mindre end 0,1 ppm? Bl.a. derfor har Forth også en operator, */, der ganger to tal og dividerer med et tredje med dobbelt præcisions mellemregning.

En af de store styrker ved Forth er, du kan definere dine egne ord, der kan bruges helt på samme måde som de foruddefinerede. Ofte er nogle få basale ord skrevet i assembler eller i C, og resten af systemet er opbygget ved at skrive nye ord ved hjælp af de få basale og atter nye ord ved hjælp af de foregående. Forth er derfor meget let at portere og er vel implementeret på stort set alt fra mainframes til de mindste microcontrollere.

Jeg har selv haft den til tider tvivlsomme fornøjelse, at skrive Forth-programmer på en PIC16 microcontroller, hvis hardwareimplementerede returstak på kun 8 pladser kraftigt begrænser den naturlige faktorering. Det har været interessant og til tider morsomt, men ikke altid lige smukt.

Andre microcontrollere, hvor man selv kan definere stakkenes størrelse, kan være en fornøjelse at skrive Forth-programmer til. Man skriver ord, der på en overskuelig måde styrer konfigurationsregistre og periferienheder, device drivere om du vil, og ud fra dem skriver man sit program, så controlleren gør, hvad man ønsker, og programmet klart viser, hvordan det foregår.

I det hele taget har Forth nok haft mest success indenfor embedded programmering, hvor jeg også har brugt det mest, men kan dog sagtens bruges til "rene PC-programmer".

Det jeg sætter mest pris på hos Forth, er nok den lette mulighed for at udvide sproget med sine egne fuldgyldige ord, hvorved man kan opbygge problemspecifikke vokabularier, der gør det let og elegant at beskrive og løse den forhåndenværende opgave.
Desuden stakken og de interaktive muligheder, som gør debugging utrolig enkel i sammenligning med mange andre sprog, hvor rutinen er programmering, kompilering, implementering, test, o.s.v., og hvor man ofte må skrive specielle testprogrammer med stubs, for at teste enkelte funktioner og procedurer.

Den udviklingscyklus har ofte også været standarden ved embedded programmering, hvor man ofte måtte kompilere og uploade sit program til controlleren for at teste det.
Takket være en simpel og genial rutine, udtænkt på universitetet i Rostock, og som du ikke skal snydes for her til sidst, kan man nu teste sine Forth-programmer interaktivt på microcontrolleren fra host computeren via en terminalforbindelse eller lign.
Rutinen, der kører på controlleren er i al sin enkelthed
: SERVER (S - ) BEGIN >STACK >STACK EXECUTE AGAIN ;
Det betyder: Definer ordet SERVER. BEGIN .. AGAIN er en uendelig løkke, >STACK henter et tal fra host computeren og lægger det på controllerens stak, og EXCECUTE kalder det ord, hvis adresse står på stakken. : indleder og ; afslutter definitionen.
Når controlleren så går til rutinen SERVER efter reset, kan man ved hjælp af få andre ord aflæse og ændre controllerens registre, manipulere i/o-porte og i det hele taget afprøve forskellige dele af programmet let og elegant fra sin host computer.

Af Forth-implementationer for Linux kan jeg nævne Gforth, http://bernd-paysan.de/gforth.html, og bigForth, http://bernd-paysan.de/bigforth.html, der begge er under GPL. Gforth har udmærket dokumentation i form af User Manual og Tutorials og står vist på de fleste distributioners pakkelister.
Kommercielle Forth-leverandører findes også. Her vil jeg blot nævne verdens ældste dedikerede Forth-firma, Forth Inc., http://www.forth.com/swiftforth/, der tilbyder SwiftForth og SwiftX, en cross compiler eller metacompiler, som det ofte kaldes, til adskillige microcontrollere.
Lignende systemer tilbyder det engelske MicroProcessor Engineering Ldt., http://www.mpeforth.com/vfxlinux.htm, med sin VFX Forth og sine cross compilers. VFX Forth inkluderer Minos, en GUI-pakke skrevet af Bernd Paysan, manden bag bigForth. En begrænset udgave af VFX Forth for Linux kan downloades fra deres hjemmeside.

Begge har bøger om Forth til salg og til download eller online læsning, ikke mindst Leo Brodie's bøger, Starting FORTH og Thinking FORTH, der trods deres efterhånden høje alder er noget af det bedste, der er skrevet om emnet.

På Rosetta Cade, http://rosettacode.org/wiki/Forth, kan du læse lidt mere og se sammenligninger mellem løsning af forskellige opgaver i mange forskellige sprog.

Forth er let at lære, og har man først fanget ideen om at faktorisere og skrive korte overskuelige definitioner, og taget den til sig, bliver man efter min mening en bedre programmør. Og ikke kun i Forth. Det er ideer og metoder, der også med fordel kan anvendes i andre sprog.
  • Log ind eller opret dig for at tilføje kommentarer

Kommentarer7

# 1

13 år siden

Permalink

Indsendt af paldepind den 9. juni 2012 kl. 11:57

Permalink

Meget meget flot post! Du

Meget meget flot post! Du burde have indsendt det som en artikel.

Mht. til faktorisering af koden så kommer det sig af, at funktioner/ord i Forth ikke tager parametre, men blot arbejder med stakken. Pga. kan man praktisk tager copy/paste kode ind i funktioner/ord.

Forth er et concatenativt programmeringssprog, her er en fin artikel om hvilke fordele dette paradigme har: http://concatenative.org/wiki/view/Concatenative%20language

#0: Man udvider blot sproget med de byggeklodser, der er nødvendige for at løse det foreliggende problem. Egentligt kan man ikke skrive nogen definitioner eller rutiner i Forth uden at udvide sproget. Derfor er Forth også blevet betegnet som et metasprog. Man bruger det til at opbygge et domænespecifikt sprog til at løse det aktuelle problem.Det forstår jeg ikke helt. Det du kalder at udvide Forth er vel bare at definere nye ord, og det er vel, selvom syntaksen til det er væsentligt simplere end i andre sprog, blot det samme som at definere nye funktioner hvilket man kan i stort set alle sprog? Når man arbejder med C/Java/Python/ect. definerer man også sine egne ord/funktioner, men det er der ikke nogen der kalder et DSL.
  • Log ind eller opret dig for at tilføje kommentarer

# 2

13 år siden

Permalink

Indsendt af marlar den 9. juni 2012 kl. 23:39

Permalink

I gymnasiet i 80'erne læste

I gymnasiet i 80'erne læste jeg om Forth og blev fascineret af det. Da jeg ikke havde adgang til at prøve sproget i praksis, lavede jeg en fuldgyldig Forth-fortolker i Comal 80. Det var faktisk ikke særligt svært selv om ikke anede et klap om fortolkere og compilere, men det viser noget om at sproget er let at implementere (bl.a. fordi det er stakorienteret) og at det derfor også er rasende hurtigt fordi det er meget maskinnært.

Jeg har dog ikke brugt det siden!
  • Log ind eller opret dig for at tilføje kommentarer

# 3

13 år siden

Permalink

Indsendt af mich den 12. juni 2012 kl. 16:23

Permalink

#1

#1:

Mange tak for roserne.
Jeg overvejede faktisk at indsende mit indlæg som en artikel, men var i tvivl om den var tilstrækkelig objektiv og neutral, og om den først skulle godkendes og/eller redigeres o.s.v.

At kalde Forth et concatenativt sprog er ret beskrivende og svarer vel mere eller mindre til at kalde det et semantisk sprog. Det er det enkelte ord, dets funktion og dets virkning på stakken, der har betydning, og rækkefølgen af ordene, der definerer funktionen.

Det er klart, at Forth og lignende sprog er lettere at faktorisere end de syntaktisk mere komplicerede, men jeg mener alligevel at ideerne kan anvendes bredere ved at tilstræbe kortere og mere overskuelige funktioner og erstatte gentagelser af kodefrakmenter med kald til en fælles funktion.
Jeg har selv tilstræbt den kodestil også i andre programmeringssprog og har konstateret, at det styrker overblikket og øger kodekvaliteten generelt.

#1: #0: Man udvider blot sproget med de byggeklodser, der er nødvendige for at løse det foreliggende problem. Egentligt kan man ikke skrive nogen definitioner eller rutiner i Forth uden at udvide sproget. Derfor er Forth også blevet betegnet som et metasprog. Man bruger det til at opbygge et domænespecifikt sprog til at løse det aktuelle problem.Det forstår jeg ikke helt. Det du kalder at udvide Forth er vel bare at definere nye ord, og det er vel, selvom syntaksen til det er væsentligt simplere end i andre sprog, blot det samme som at definere nye funktioner hvilket man kan i stort set alle sprog?

Både og. Du kan da definere funktioner i mange sprog, men de bliver ikke en del af sproget. Til forskel er der ikke noget der adskiller Forth-ord, du selv definerer, fra de forud definerede. De kan alle bruges på nøjagtig samme måde. Der er ikke alle tænkelige funktioner i Forth som standard, men det er let at lave, dem du mangler. Mangler du f.eks. kvadrat og 3. potens for heltal, skriver du blot
: ^2 ( n -- n^2 ) dup * ;
: ^3 ( n -- n^3 ) dup ^2 * ;

I (de fleste) andre sprog må man definere lignende udvidelser som en funktion, der skal kaldes med den særlige syntaks, der gælder for funktioner, mens de i Forth er fuldstændig integreret i sproget.

Tydeligere og mere kraftfuldt ses det i Forths definerende ord, der sådan set er Forths compiler.
Der er naturligvis allerede en række definerende ord i Forth som standard, f.eks. create, variable, constant og : , men brugeren kan let selv skrive nye definerende ord og på den måde udvide compileren, hvilket ikke er trivielt i de fleste andre sprog.
Jeg så det engang beskrevet i en artikel under overskriften "Skriv din egen compiler på fire linier".
  • Log ind eller opret dig for at tilføje kommentarer

# 4

13 år siden

Permalink

Indsendt af mich den 12. juni 2012 kl. 16:34

Permalink

#2

Ja, dengang skulle enhver hacker med respekt for sig selv jo helst implementere sin egen Forth - og mange gjorde det. :-)
På den tid blev de fleste "hjemmedatamater" leveret med en BASIC-fortolker (og ikke ret meget andet), men der kom en, Jupiter Ace , tror jeg den hed, der havde en Forth-fortolker, og den var hurtig, selv om hardwaren var sammenlignelig. Fagbladene sammenlignede præstationerne, og den gav de andre baghjul så man dårligt så røgen.
  • Log ind eller opret dig for at tilføje kommentarer

# 5

13 år siden

Permalink

Indsendt af marlar den 12. juni 2012 kl. 19:58

Permalink

Jeg husker godt Jupiter

#4:
Jeg husker godt Jupiter Ace. På det tidspunkt havde jeg en ZX81, og til den fik jeg en Forth-rom. Rom var dengang noget meget håndgribeligt, man satte simpelthen en klods ned på et lille print!
  • Log ind eller opret dig for at tilføje kommentarer

# 6

13 år siden

Permalink

Indsendt af phomes den 14. juni 2012 kl. 23:28

Permalink

på forsiden med den :)

på forsiden med den :)
  • Log ind eller opret dig for at tilføje kommentarer

# 7

12 år 8 måneder siden

Permalink

Indsendt af SPAMMER (not verified) den 22. oktober 2012 kl. 10:18

Permalink

Håbede på at Shank ville

SPAM
  • Log ind eller opret dig for at tilføje kommentarer

Svar søges

llumos Unix-operativsystem, 0
Den er go 0
14. februar = I Love Free Software Day 0
Lokal fil-deling - for de dovne. 0
Linux fra begynder til professionel af O'Reilly 0

Seneste aktivitet

En snak om Linux-kompatibel software 3
Nulstilling af adgangskode 6
Virtuel maskine? 2
PCLinuxOS 27
Gode anmeldelser Zorin OS 17.3 3
Open Source-eksperimentet 3
"Intet realistisk alternativ" - mig i r*ven 15
Ingen Mint 5
Linux App Store Flathub når 3 milliarder downloads 2
Digitaliseringsministeriet sætter gang i pilotprojekt om digital suverænitet 3
Mest sikker webbrowser 5
Firefox 2
Privatbeskeder 7
Backup/synkronisering? 3
BigLinux 5
Chatgpt satire 1
Læsning af databasefil i Firefox 2
Vanilla OS 15
Pepsi Challenge 4
Linuxin er nu migreret til Drupal 11 13

© 2025 Linuxin og de respektive skribenter

Oprettet og drevet af nørder siden 2004 !