FORTH - Der Thread zur Programmiersprache

Dein Hive sagt kein Pieps mehr? Du hörst kein Heartbeat-Ton? Hier findest Du Hilfe.
Benutzeravatar
yeti
Beiträge: 2300
Registriert: Fr 27. Aug 2010, 14:48
Wohnort: Wrong Planet
Kontaktdaten:

Re: Auch Probleme mit der Forth Variante

Beitrag von yeti »

Klaus-Peter hat geschrieben:Kann man den Titel eines Thread eigentlich nachträglich noch ändern ?
Wenn Du den ersten Beitrag des Threads änderst ist das Ändern der Thread-Titelzeile auch möglich.

----------8<----------
Edit 20120128: --Typos ... soviel Zeit muß sein!
Zuletzt geändert von yeti am Sa 28. Jan 2012, 18:26, insgesamt 1-mal geändert.
𝖂𝖎𝖗 𝖐𝖔̈𝖓𝖓𝖊𝖓 𝖆𝖑𝖑𝖊𝖘 𝖆𝖚𝖘𝖘𝖊𝖗 𝖎𝖓 𝕱𝖗𝖚̈𝖍𝖑𝖎𝖓𝖌, 𝕾𝖔𝖒𝖒𝖊𝖗, 𝕳𝖊𝖗𝖇𝖘𝖙 𝖚𝖓𝖉 𝖂𝖎𝖓𝖙𝖊𝖗! – 𝕯𝖊𝖚𝖙𝖘𝖈𝖍𝖑𝖆𝖓𝖉.
"Du willst hier nicht klicken. Dies interessiert Dich nicht." — Yeti.
"DNA is a four letter word!" — Yeti.
Benutzeravatar
drohne235
Administrator
Beiträge: 2284
Registriert: So 24. Mai 2009, 10:35
Wohnort: Lutherstadt Wittenberg
Kontaktdaten:

Re: Auch Probleme mit der Forth Variante

Beitrag von drohne235 »

Also könnte ich eine immerwiederkehrende Formel zum Beispiel in ein "WORD" packen, um somit eine übersichtlichere Struktur im Forth Programm zu haben? Oder bestimmte Abfragen ebenfalls?
In erster Linie sind Worte in Forth gleichbedeutend mit Unterprogrammen in anderen Sprachen. Beim programmieren zerlegst du das Problem in entsprechende sinnvolle Teilfunktionen, welche du schrittweise als Wort realisierst. Schau dir mal diesen Text im Download an:

http://hive-project.de/wp-content/uploa ... sophie.pdf

Wenn du also eine Waschmaschine programmieren möchtest, hast du vielleicht folgendes Wort:

: kochwäsche
wassereinlauf 95 grad heizung 60 min trommel aus heizung wasserauslauf spülen schleudern ;

Dieses Wort beschreibt dein Problem wie eine Kochwäsche abläuft - zumindest nach meinem Kentnissstand... ;) Für dieses Wort benötigst du aber nun wieder einige Worte wie "Wassereinlauf" usw., die im Grundwortschatz nicht vorhanden sind:

: wassereinlauf \ füllt die maschine mit wasser
ein einlauf schalten
5 min warten
aus einlauf schalten ;

: wasserauslauf \ leert die waschmaschine
ein auslauf schalten
5 min warten
aus auslauf schalten ;

: spülen
wassereinlauf
1 min trommel
wasserauslauf ;

: schleudern
ein auslauf schalten
10 min trommel
aus auslauf schalten ;

usw.

Bei der Sequenz "95 grad heizung" wird ein Temperaturwert in °C auf dem Stack übergeben, "grad" wandelt ihn in einen für die Heizsteuerung nötigen Wert und "heizung" stellt diese Temperatur ein.

Die reale Programmierung in Forth findet natürlich in anderer Richtung als hier beschrieben statt, da ja beim compilieren eines Wortes immer schon die verwendeten Worte im Wörterbuch sein müssen. Man beginnt als immer mit den grundlegenden Worten, testet diese sofort und baut aus diesen Worten komplexere Sachen, bis man ausgehend vom Grundwortschatz bis zu einem Wort kommt, welches mein Problem beschreibt bzw. löst.

Im Prinzip ist das aber bei vielen Sprachen ähnlich. Bei Forth gibt es aber einige coole Besonderheiten:

1. Unterprogrammaufrufe haben extrem geringe "Kosten".
2. Wort = Unterprogramm|Daten + Datensatz
3. Sehr effiziente Testmöglichkeiten.
4. Forth ist in Forth programmiert.

Ich bin kein Forthprofi, deshalb entspricht das mehr meinem persönlichen Verständnis.

Zu 1. Unterprogrammaufrufe haben extrem geringe "Kosten".: Forth verwendet zwei Stacks: einen Return- und einen Datenstack. Die meisten anderen Sprachen, wie auch Spin, verwenden nur einen Stack. Wenn nun in Spin ein Unterprogramm aufgerufen wird, so werden alle Übergabeparameter auf den Stack geschaufelt inklusive abschließend die Returnadresse. Dann verarbeitet das Unterprogramm die Daten auf dem Stack, speichert das Ergebnis wieder auf diesem und führt ein Return aus. Das aufrufende Programm holt sich nun wieder das Ergebnis vom Stack und macht weiter. Das sind massig Stackoperationen bei einem einzigen Unterprogrammaufruf, also auch eine hoher Zeitaufwand (Kosten).

In Forth bleiben Daten fast immer direkt auf dem Datenstack und werden direkt und ohne Kopieraktionen dort verarbeitet. Ein Wort muss also nicht erst die Übergabeparameter auf den Stack speichern, da diese sich in den meisten Fällen schon dort befinden. Für einen Unterprogrammaufruf fallen also auch kaum "Kosten" in Form von Ausführungszeit für das Parameterhandling an.

Was bringt's: In Forth kann man Teilprobleme ohne Aufwand in sehr kleine Bausteine zerlegen. Damit ist die Speicherauslastung sehr effizient. Wenn man zum Beispiel in Spin so programmiert, wird man feststellen, das das Programm sehr langsam, je mehr man das Programm in Teilprobleme in Form von Unterprogrammen zerlegt - viel langsamer als Forth. Es hat schon seinen Grund, das Femto-Basic im wesentlichen aus einigen gigantischen Unterprogrammen besteht. Man könnte diese zwar sehr übersichtlich in Teilprobleme/Unterprogramme zerlegen, aber dann wäre das Basic extrem langsam. Schau es dir mal an, da gibt es Routinen, welche über viele Bildschirmseiten gehen!

Und jetzt betrachte mal die Forth Quelltext: Dort wirst du viele Worte finden, die teilweise nur Einzeiler sind. Das spart sehr viel Speicher, ist sehr gut zu testen und übersichtlich.

Zu 2. Wort = Unterprogramm|Daten + Datensatz: Ein Wort in Forth enthält nicht nur ein Unterprogramm, sondern auch Informationen wie den Namen der Routine, um diese Funktion zu verwalten. Das Wörterbuch ist dabei wie eine minimalistische Datenbank in Form einer verketteten Liste, in welcher die Routinen verwaltet werden können. Und zusätzlich enthält Forth nun auch Worte, um genau diese Verwaltungsfunktionen zu realisieren, wie zum Beispiel "forget" und "words".

Aber ein Wort muss nicht nur Programmcode, sondern kann auch Daten enthalten. Eine Variable oder Konstante ist solch ein Beispiel: Dabei wird ein Wort compiliert, welches einen Datenwert enthält und gleichzeitig die Information, mit welchem anderen Wort diese Daten verarbeitet werden können. Ruft man nun eine Variable auf, wird der Code ausgeführt um mit dieser Variable umzugehen: Dieser Code legt die Adresse der Variable auf den Stack und nun kann mit ! oder @ auf diese Variable zugegriffen werden.

3. Sehr effiziente Testmöglichkeiten: Wenn ich meine Waschmaschine programmiere, kann ich sofort mit "ein auslauf schalten" oder "aus auslauf schalten" die Funktion testen. Ich muss nicht erst eine Testumgebung programmieren, denn alles was man man zum testen benötigt (im wesentlichen der Interpreter und die Datenübergabe per Datenstack) ist immer im Forth enthalten.

4. Forth ist in Forth programmiert: Der Forthcompiler, der Interpreter und alle anderen Aspekte sind in Form von vielen Bausteinen (Worten) direkt in Forth programmiert. So kann man problemlos auch den Compiler direkt in Forth erweitern oder man kann schauen, wie die bestehenden Worte arbeiten, indem man einfach in die Quelltexte schaut.

Was momentan aber im Forth auf dem Hive noch fehlt, ist ein Quelltexteditor.
Wie baue ich ein Programm auf. Gibt es hier auch Programmzeilen wie im Basic?
Ich glaube ich verstehe die Frage nicht - was verstehst du unter Programmzeilen?

: sqr ( n -- n*n )
dup * ;

Dieses Wort berechnet das Quadrat von n und legt das Ergebnis auf dem Stack ab. Das sind zwei Programmzeilen, man könnte es aber auch als ": sqr dup * ;" in eine Zeile packen. Was meinst du genau?
"Ob Sie denken, dass Sie es können, oder ob Sie denken, dass Sie es nicht können - in beiden Fällen haben Sie recht." Henry Ford
quix
Beiträge: 233
Registriert: Sa 22. Okt 2011, 16:10

Re: Auch Probleme mit der Forth Variante

Beitrag von quix »

Zu den Programmzeilen am Beispiel "wassereinlauf". Ich geben also die Zeilen (Zeile für Zeile) in Forth ein. Nach jeder Zeile drücke ich Enter(oder auch Return). Will ich nun nach ein paar Zeilen, eine weiter oben schon geschriebene Zeile ändern, was mach ich da. (Im Vergleich in Basic gebe ich die Zeile mit der selben Zeilennummer neu ein und die alte wird überschrieben.)

Wie werden diese Zeilen "gehandelt" und wie kann ich diese wieder editieren?

Wie weiß Forth, wo meine neue Routine (Neues WORD?!) beginnt und wo es endet?


: wassereinlauf \ füllt die maschine mit wasser
ein einlauf schalten
5 min warten
aus einlauf schalten ;

In Basic würde das nach meinem Wissensstand in etwa so aussehen:

10 REM Unterprogramm wassereinlauf \ füllt die maschine mit wasser
20 OPEN einlauf, ON: REM ein einlauf schalten
30 PAUSE 300: REM 5 min warten
40 CLOSE einlauf, OFF: REM aus einlauf schalten
50 END
BorgKönig
Beiträge: 598
Registriert: So 24. Mai 2009, 11:24

Re: Auch Probleme mit der Forth Variante

Beitrag von BorgKönig »

ich glaube, hier beissen sich gerade die varianten der programmierung: logisch vs. strukturiert.

basic ist strukturel zu programmieren, forth dagegen logisch. bei forth fängt man bei der kleinsten, bzw. ersten aufgabe an. also, waschmaschine füllen, dann einschalten usw... ;)
quix
Beiträge: 233
Registriert: Sa 22. Okt 2011, 16:10

Re: Auch Probleme mit der Forth Variante

Beitrag von quix »

Also gebe ich die Struktur, den Programmablauf also, Schritt für Schritt ein. Und was mache ich, wenn ich merke, dass weiter vorn sich ein Fehler eingeschlichen hat? Oder ich möchte mittendrin eine Routine/WORD verbessern. Wie geht das?
Benutzeravatar
drohne235
Administrator
Beiträge: 2284
Registriert: So 24. Mai 2009, 10:35
Wohnort: Lutherstadt Wittenberg
Kontaktdaten:

Re: Auch Probleme mit der Forth Variante

Beitrag von drohne235 »

Momentan gibt es keinen Editor zum bearbeiten des Quelltextes direkt auf dem Hive. Ich editiere deshalb momentan auf dem Host und füge per Copy/Past im Terminal auf COG 6 ein. Wenn ein Wort falsch war, so kann man das mit dem Befehl "forget" aus dem Wörterbuch löschen. Allerdings löscht Forget ALLE Wörter ab dem Namen:

: t1 ... ;
: t2 ... ;
: t3 ... ;

forget t3 \ Löscht nur das Wort t3, da es das letzte ist.
forget t1 \ Löscht AB dem Wort t1, also auch t2, welches sich im Wörterbuch hinter t1 befindet.

Nach dem löschen kann man das Wort dann neu definieren. Aber man kann Wörter auch mehrmals definieren, versuch mal folgendes:

Code: Alles auswählen

Prop0 Cog6 ok
: t1 ." Hallo erste Welt!" cr ;
Prop0 Cog6 ok
: t2 t1 ;
Prop0 Cog6 ok
: t1 ." Hallo zweite Welt!" cr ;
Prop0 Cog6 ok
: t3 t1 ;
Prop0 Cog6 ok
t2
Hallo erste Welt!
Prop0 Cog6 ok
t3
Hallo zweite Welt!
Prop0 Cog6 ok
Obwohl t2 und t3 im Prinzip den gleich sind, also in unserem Fall einfach t1 aufrufen, wird bei t2 das erste t1 und bei t3 das zweite t1 verwendet. Mit "words" kannst du es auch überprüfen: t1 ist zweimal im Wörterbuch vorhanden. Wird nun ein neues Wort compiliert, so startet der Compiler seine Suche immer vom letzten Wort im Wörterbuch - findet und verwendet dem entsprechend die letzte Version eines Wortes. Also aufpassen! ;)
Wie weiß Forth, wo meine neue Routine (Neues WORD?!) beginnt und wo es endet?
nun ja, Basic mit seinen Zeilennummern ist da auch ein Sonderfall bei den Programmiersprachen. Alle anderen Sprachen verzichten auf Zeilennummern. Im übrigen verwenden auch neuere Basic-Versionen keine Zeilennummern mehr. Forth verwaltet alles als Wort und ich kann diese Worte über ihren Namen ansprechen: der Interpreter oder Compiler sucht dann im Wörterbuch nach dem Namen. Wird das Wort gefunden, so ist die Startposition im Speicher ja bekannt und im Wortheader sind entsprechende Informationen um zum Beispiel die Länge des Wortes zu bestimmen - da braucht man keine Zeilennummern.
"Ob Sie denken, dass Sie es können, oder ob Sie denken, dass Sie es nicht können - in beiden Fällen haben Sie recht." Henry Ford
quix
Beiträge: 233
Registriert: Sa 22. Okt 2011, 16:10

Re: Auch Probleme mit der Forth Variante

Beitrag von quix »

Erst mal verstanden. Also den Editor gibt es noch nicht. Das mache ich also am angeschlossenem Host mit dem Terminalprogramm. Langsam verschwinden die Nebelschwaden. Dass Basic so ein extremer Sonderfall, war mir nicht klar. Aber dass es keine Programmzeilen in dem Sinne gibt, ist so auch nicht richtig. Spin zum Beispiel (was anderes fällt mir auf die Schnelle nicht ein) listet den Quelltext in einem Fenster auf, welches am linken Rand auch durchnummerierte Zeile hat. Also für mich auch eine Art Nummerierung. Und die Fehlermeldungen gibt Spin auch mit Hilfe der Zeilennummern an.

Ist es denn nun möglich, analog zu Basic, Forth von Regime aus aufzurufen? Ich meine damit, dass der HIVE zuerst mit Regime startet und dann Forth aufgerufen werden kann? Und dass diese Terminal-Prozedur wegfällt? Wenn ich aus Versehen den Eprom mit anderen Programmen flashe, muss ich ja alles wieder von vorn flashen. Wäre das möglich?
Klaus-Peter
Beiträge: 754
Registriert: Sa 29. Okt 2011, 14:34

Re: FORTH - Der Thread zur Programmiersprache

Beitrag von Klaus-Peter »

So, hab den Thread mal umbenannt,

besten Dank an yeti für die Hilfestellung :D
Drohne 206 ist ein HIVE R14-u
Drohne 266 ist ein HIVE R14-V
Der Mensch ist das wichtigste und kostbarste Peripheriegerät einer Computeranlage.
Benutzeravatar
drohne235
Administrator
Beiträge: 2284
Registriert: So 24. Mai 2009, 10:35
Wohnort: Lutherstadt Wittenberg
Kontaktdaten:

Re: Auch Probleme mit der Forth Variante

Beitrag von drohne235 »

quix hat geschrieben:Aber dass es keine Programmzeilen in dem Sinne gibt, ist so auch nicht richtig. Spin zum Beispiel (was anderes fällt mir auf die Schnelle nicht ein) listet den Quelltext in einem Fenster auf, welches am linken Rand auch durchnummerierte Zeile hat. Also für mich auch eine Art Nummerierung. Und die Fehlermeldungen gibt Spin auch mit Hilfe der Zeilennummern an.
Die Zeilennummern sind aber für die Programmausführung völlig irrelevant, und nur für Fehlermeldungen von Interesse. Wenn ich in meinem Texteditor für die Forth-Quelltexte eine Zeilennummerierung anschalte, stehen da auch Zeilennummern, aber die sind ebenso überflüssig und deshalb arbeiet Forth immer noch nicht mit eilennummern. Die Besonderheit und auch eine Schwäche von Basic war, das der Programmflusss selbst über diese Zeilennummern adressiert wurde. Man schrieb also etwas wie "goto 1234" um irgendwo hinzuspringen und DAS gibt es so meines Wissens in keiner anderen Sprache. Die Schwäche bestand darin, dass dieses Konzept zu dem legendären Spaghetti Code führt.
quix hat geschrieben:Ist es denn nun möglich, analog zu Basic, Forth von Regime aus aufzurufen? Ich meine damit, dass der HIVE zuerst mit Regime startet und dann Forth aufgerufen werden kann? Und dass diese Terminal-Prozedur wegfällt? Wenn ich aus Versehen den Eprom mit anderen Programmen flashe, muss ich ja alles wieder von vorn flashen. Wäre das möglich?
Im Prinzip wäre das über eine Änderung der basics.mod möglich, aber warum? Ist doch toll das eine Sprache wie bei den alten Homecomputern gleich startet. Ich habe sogar darüber nachgedacht, Regime wegzulassen, da man ja fast alles was Regime kann auch in Forth machen kann. Naja, und den EEPROM braucht man doch im Normalfall nicht anfassen. Im Prinzip könnte man aber diese Terminalgeschichte auch noch in den regflash integrieren, aber dafür fehlt mir einfach die Zeit, ist ein nicht unerheblicher Aufwand.
"Ob Sie denken, dass Sie es können, oder ob Sie denken, dass Sie es nicht können - in beiden Fällen haben Sie recht." Henry Ford
quix
Beiträge: 233
Registriert: Sa 22. Okt 2011, 16:10

Re: FORTH - Der Thread zur Programmiersprache

Beitrag von quix »

Hier mal eine kleine Präsentation für Dummys zur Einführung in Forth:

http://strotmann.de/roller/cas/entry/ta ... marks_from
Antworten