Gibt es eine Wann-Aussage? [geschlossen]

12

Gibt es eine Sprache oder eine Sprachfunktion, die "Wann" -Fälle verarbeiten kann? Das heißt, wenn eine Bedingung in einem beliebigen Bereich oder Kontext erfüllt wird, kann dieser zusätzliche Code zur Ausführung angegeben werden?

Beachten Sie, dass dies von einem einfachen abweicht if, der in einem bestimmten Umfang und ausdrücklich geschrieben sein muss. Diese when-Klausel gleicht fast einer Klausel if, die in jedem Fall bei der Ausführung des darauf folgenden Programms angewendet wird.

Macneil
quelle
1
SQL Server: select case table1.col1 when 1 then 'Y' else 'N' end as col1_yn from .... Außerdem: msdn.microsoft.com/en-us/library/dd233249.aspx Grundsätzlich würde ich mithilfe der Google- Codesuche nach "when" suchen.
Job
5
@Job: Das ist eine Klausel, keine Aussage.
Ben Voigt
2
Du meinst wie in Verilog?
Dan04
2
Benötigt mehr Beschreibung ... sehr breite Frage.
WernerCD
2
Die Frage wird hier auf Meta diskutiert .
Adam Lear

Antworten:

25

Ihre Frage ist nicht klar, aber das Observer-Muster scheint das zu sein, wonach Sie suchen: http://en.wikipedia.org/wiki/Observer_pattern

Victor Hurdugaci
quelle
1
Ja, was ich gefragt habe, scheint eine native Implementierung dafür zu sein. Ich möchte auch auf einen interessanten Artikel zur reaktiven Programmierung verweisen, der unten veröffentlicht ist und "das Beobachtermuster missbilligt" (kein Link, STRG + F). Eine when-Anweisung würde theoretisch immer dann einen Codeblock ausführen, wenn während der Ausführung des Programms eine Bedingung erfüllt ist - unabhängig davon, wie dies implementiert wird - und würde die Arbeit von mindestens mir erleichtern, der stattdessen das implementieren muss Beobachtermuster von mir.
WindScar
15

Syntaxmäßig haben einige Sprachen ein whenSchlüsselwort, aber mir ist keine Sprache bekannt, die es so verwendet, wie Sie es beschreiben.

Das Muster "Wenn X, mach Y" ist eine Art Kern der aspektorientierten Programmierung: Anstatt einen linearen Ablauf zu definieren, binden Sie Handler in bestimmte Bedingungen ein (auch als "Abonnieren" eines "Ereignisses" bezeichnet). Diese Art der Programmierung ist in GUI-Anwendungen beliebt, in denen die Kernroutine des Programms ein Event-Dispatcher ist.

Einige Sprachen verfügen über umfangreiche Syntaxfunktionen, um solche Mechanismen über Sprachkonstrukte bereitzustellen. Ein Beispiel wäre C # mit seinen Delegierten und Ereignissen:

// 'when btnOK is clicked, run HandleOKClick'
btnOK.Clicked += this.HandleOKClick;

Andere Sprachen verwenden OOP-Konstrukte (Beobachtermuster, Ereignis-Listener usw.; ein Beispiel in Java (mein Java ist ein bisschen verrostet, also können Sie es gerne bearbeiten):

Foobar f = this;
btnOK.registerClickHandler(
    new ClickHandler {
        public void handleClick(Event e) {
            f.handleOKClick(e);
        }
    });

Ein weiterer Ansatz ist die Verwendung von einfachen alten Rückrufen. Beispiel in Javascript:

var btnOK = $('btnOK');
btnOK.click(handleOKClick);
tdammers
quelle
15

Bisher hat noch niemand erwähnt INTERCAL ‚s comefrom :

COMEFROM wurde ursprünglich in Listen von Anweisungen für Witzassemblersprachen (als 'CMFRM') gesehen. Es wurde in einem Datamation-Artikel von R. Lawrence Clark aus dem Jahr 1973 beschrieben, der als Antwort auf Edsger Dijkstras Brief Go To Statement Considered Harmful verfasst wurde. COMEFROM wurde schließlich in der C-INTERCAL-Variante der esoterischen Programmiersprache INTERCAL zusammen mit dem noch obskureren 'berechneten COMEFROM' implementiert. Es gab auch Fortran-Vorschläge für "Zugewiesenes KOMMEN VON" und ein "NICHT" -Schlüsselwort (zur Ergänzung der vorhandenen "DO" -Schleife).

Am 1. April 2004 veröffentlichte Richie Hindle eine Implementierung von GOTO und COMEFROM für die Programmiersprache Python. Obwohl sie am Aprilscherz veröffentlicht wurden und nicht für den ernsthaften Gebrauch bestimmt sind, ist die Syntax gültig und die Implementierung funktioniert vollständig.

Matthieu
quelle
7
... und du musstest es verderben! :-)
Stephen C
2
O rly?
Ben Voigt
2
@BenVoigt: Ihre Antwort enthielt zum Zeitpunkt der Veröffentlichung weder "Intercal" noch "COMEFROM".
DeadMG
2
@DeadMG: Meine Antwort enthielt " en.wikipedia.org/wiki/COMEFROM " von der ersten Version an.
Ben Voigt
2
@BenVoigt: Das zählt nicht.
DeadMG
6

Die Tcl-Sprache enthält Ablaufverfolgungen für Variablen, mit denen beliebiger Code ausgeführt werden kann, wenn eine Variable gesetzt (oder gelesen oder gelöscht) wird. Dies ist hier jedoch weniger wichtig. Dieser willkürliche Code kann leicht das Auswerten eines Ausdrucks und das Ausführen von Code einschließen, wenn er gültig ist. Die Haupteinschränkung besteht darin, dass dies zwar für lokale Variablen möglich ist, im Allgemeinen jedoch nicht sehr nützlich ist, da sie in der Regel eine sehr kurze Lebensdauer haben. Daher sind solche Dinge normalerweise auf globale Variablen und Namespace-Variablen beschränkt. (Tcl hat keine Verschlüsse.)

Aber wenn Sie dies tun, sollten Sie vorsichtig sein. Obwohl Sie offiziell keine Probleme mit dem Wiedereintritt haben (die Ablaufverfolgung ist für die Dauer der Ausführung des Körpers deaktiviert), ist es dennoch eine großartige Möglichkeit, unklaren Code zu schreiben und viel Verwirrung zu stiften. Es ist auch eine wirklich schreckliche Idee, sie mit einer Schleifenvariablen (außer zum Debuggen) zu verwenden, da der Leistungseinbruch sehr bedeutend sein kann.


Ein Beispiel (basierend auf dem Code der oben verlinkten Handbuchseite) veranschaulicht dies.

set foo 1
set bar 2
proc doMult args {
    global foo bar foobar
    set foobar [expr {$foo * $bar}]
}
trace add variable foo write doMult
trace add variable bar write doMult
doMult

Von diesem Punkt an wird jedes Mal, wenn eine $foooder $bareine neue ganze Zahl $foobarwird, das Produkt der beiden. Automatisch.


Mit Tcl kann Code auch für andere Arten von Triggern ausgeführt werden, z. B. für die Ausführung von Befehlen, das Löschen von Befehlen, Timer, die Verfügbarkeit von Daten auf Sockets usw. Mit der hinzugefügten Tk-Bibliothek wird dies um eine ganze Reihe erweitert von GUI-Ereignissen als auch. Es ist wahr, dass Tcl eine sehr stark ereignisorientierte Sprache ist (auch wenn Sie leicht Code schreiben können, der keine dieser Funktionen verwendet).

Donal Fellows
quelle
4

So etwas wie Eventhandling?

statt func () behandelt event

du sagst wann event do func

Oder vielleicht ein Rückruf zu einer bestimmten Variable?

Akash
quelle
Klingt auf jeden Fall nach einem Ereignis.
Ton Plomp
4

Ja, es gibt ein solches Schlüsselwort in Perl als Anweisungsmodifikator:

say 'Well done!'        when 'A';

Es ist auch Teil der switch-Anweisung:

given ($foo) {
    when (/^abc/) { $abc = 1; }
    when (/^def/) { $def = 1; }
    when (/^xyz/) { $xyz = 1; }
    default { $nothing = 1; }
}
Ubiquité
quelle
5
Ich kenne Perl nicht, aber dieses "Wann" sieht für mich eher wie ein "Wenn" aus ... Ich denke, die Frage bedeutet den "Wann <Ereignis> <Aktion>" -Typ "Wann".
ShdNx
1
Riecht nach einer switchAussage für mich. (Mit Messing auf es Knöpfe, aber dann wieder es ist Perl ...)
Donal Fellows
Eigentlich ist das caseeine switchAussage. Genau wie in Ada.
Mouviciel
4

Zählt das ( COMEFROMAussage auf Wikipedia beschrieben) ?

Zusammenfassung:

COMEFROM ist ungefähr das Gegenteil von GOTO, da es den Ausführungsstatus von jedem beliebigen Punkt im Code in eine COMEFROM-Anweisung übernehmen kann. Der Punkt im Code, an dem die Statusübertragung stattfindet, wird normalerweise als Parameter an COMEFROM übergeben. Ob die Übertragung vor oder nach der Anweisung am angegebenen Übertragungspunkt erfolgt, hängt von der verwendeten Sprache ab. Abhängig von der verwendeten Sprache können mehrere COMEFROMs, die auf denselben Abfahrtspunkt verweisen, ungültig sein, nicht deterministisch sein, in einer definierten Priorität ausgeführt werden oder sogar eine parallele oder anderweitig gleichzeitige Ausführung auslösen, wie in Threaded Intercal dargestellt.

Ben Voigt
quelle
6
Ich sehe, woher du kommst.
Pubby
6
-1 für einen Link ohne Zusammenfassung; Linkrot kann passieren.
Hugo
5
@Ben - Unabhängig davon, Ihre Antwort wäre viel besser, wenn Sie sich die Mühe machen, etwas mehr als 3 Wörter zu schreiben.
Blackjack
3
@BenVoigt: In diesem Fall hätten Sie einfach den gesamten Link einfügen können, anstatt ihn hinter "this" zu verstecken.
Marjan Venema
1
@BenVoigt: Mein Punkt war, dass Sie den gesamten Link eingefügt hatten, anstatt ihn dahinter zu verstecken. Die zu suchenden Wörter würden sofort im Text Ihrer Antwort sichtbar sein, anstatt nur, wenn Sie den Mauszeiger über den Link halten ... Außerdem stimme ich BlackJack und Hugo zu, dass eine Antwort, die hauptsächlich aus einem Link besteht, zumindest eine kurze Zusammenfassung dessen enthalten sollte, was dort zu finden ist. Es hilft sicherzustellen, dass StackExchange auf eigenen Beinen stehen kann, auch wenn der Link rotiert.
Marjan Venema
3

Suchen Sie eine Sprache mit einer synchronen oder einer asynchronen when-Anweisung?

Klingt für mich nach einem Ereignismuster (/ Abonnement / Rückruf).

Z.B

conditionOwner.Condition += listener.WhenCondition

Immer wenn der Bedingungseigner benachrichtigt, dass die Bedingung eingetreten ist, führt der Listener WhenCondition () aus.

Sie können ein Bindungsmuster mit einem Konverter verwenden, der den Status mehrerer Eingabevariablen überprüft (bei Änderung) und die Bedingung berechnet. Anschließend können Sie eine Eingabeeigenschaft des Listeners an die Ausgabe binden und handeln, wenn diese Eingabe geändert wird.

In Bezug auf Sprachen hat beispielsweise .NET (z. B. C #) synchrone Subskriptionen (Ereignisse) eingebaut, und seine Reactive Extensions (RX) fügen asynchrone Subskriptionen hinzu.

Danny Varod
quelle
3

Die Beschreibung klingt wie ein Datenbank-Trigger, der darauf ausgelegt ist, ein bestimmtes Szenario abzuwarten und dann auszuführen.

Aus Wikipedia:

Ein Datenbank-Trigger ist prozeduraler Code, der automatisch als Reaktion auf bestimmte Ereignisse in einer bestimmten Tabelle oder Sicht in einer Datenbank ausgeführt wird. Der Trigger wird hauptsächlich verwendet, um die Integrität der Informationen in der Datenbank aufrechtzuerhalten. Wenn beispielsweise ein neuer Datensatz (der einen neuen Mitarbeiter darstellt) zur Mitarbeitertabelle hinzugefügt wird, sollten neue Datensätze auch in den Tabellen der Steuern, Urlaube und Gehälter erstellt werden.

http://en.wikipedia.org/wiki/Database_trigger

user1249
quelle
3

Sie sprechen von weniger Syntax als von Struktur . whenIn einem System, das eine endliche Menge an Logik ausführt, dann die whenAnweisungen ausführt , dann eine Schleife durchläuft und die Logik erneut ausführt, könnte man wirklich nur eine solche Anweisung haben, die in einer Endlosschleife fortgesetzt wird.

Beispielsweise ist die Windows-Programmierung typischerweise "ereignisbasiert". Das Abonnieren eines Schaltflächenereignisses bedeutet im ClickWesentlichen "Tun Sie dies, wenn Sie darauf klicken". Was sich jedoch unter der Haube abspielt, ist eine Nachrichtenverarbeitungsschleife. Windows sendet eine Nachricht an die Anwendung, wenn der Benutzer auf die Schaltfläche klickt und die Nachrichtenverarbeitungsschleife in der Anwendung den entsprechenden Ereignishandler ausführt.

Wenn Sie Ereignisse beispielsweise in C # verwenden, können Sie dies ohne eine Meldungsschleife tun. Die Einschränkung besteht jedoch darin, dass Sie das Ereignis im Voraus deklarieren müssen, sodass Sie keine Artibrary- whenAnweisung schreiben können , die auf irgendeine Art von überwacht Zustand. Sie müssen auf ein bestimmtes Ereignis warten.

Um dieses Verhalten in einer Von Neumann-Architektur zu erzielen, müssen Sie eine Endlosschleife ausführen, die bei jeder Ausführung des entsprechenden Codes den entsprechenden Code auf alle Bedingungen überprüft. Intern erhalten Sie nur eine große Liste von if/ thenoder switchAussagen. Die meisten Desktop-Anwendungen und Web-Programmierer würden sich übergeben, wenn sie ein solches Konstrukt sehen würden, sodass es wirklich nur dann schmackhaft ist, wenn Sie es in eine Art syntaktischen Zucker wie das Windows-Ereignismodell einwickeln (auch wenn dies unter der Haube geschieht).

Auf der anderen Seite ist dieses Programmiermodell sehr verbreitet, wenn Sie sich mit der Entwicklung eingebetteter Firmware, Echtzeit-Führungskräften oder industriellen Controllern befassen. Wenn Sie beispielsweise ein Echtzeitprogramm haben, möchten Sie möglicherweise Folgendes ausdrücken:

outputA = input1 && input2

Der Code ist einfach zu verstehen (weil er deklarativ ist). Damit es funktioniert, müssen Sie es jedoch in einer engen Schleife ausführen. Sie bewerten outputAjedes Mal durch die Schleife neu. Viele Desktop- oder Web-Programmierer würden das nicht mögen, weil es ineffizient ist. Für sie ist das einzige Mal, dass Sie neu bewerten sollten, outputAwann input1oder input2Änderungen. Sie würden lieber etwas sehen, das Sie beschreiben:

when input1 changes
    evaluateOutputA()

when input2 changes
    evaluateOutputA()

evaluateOutputA()
    outputA = input1 && input2

Wenn Sie dies möchten (und ich persönlich bevorzuge diese Idee nicht) und Ihr Ziel die Effizienz ist, müssen Sie sich immer noch fragen, was der Prozessor unter der Haube tut. Offensichtlich läuft immer noch eine Art Schleife, die die Eingabezustände jedes Mal mit den vorherigen Eingabezuständen vergleicht und bei jeder Änderung den entsprechenden Code ausführt. Es ist weniger effizient und schwieriger zu lesen und zu warten.

Wenn andererseits die Arbeit, die Sie bei input1Änderungen leisten müssen, erheblich ist, ist Ihre whenKlausel möglicherweise sinnvoll. In SPS wird diese Art der Anweisung als "Erkennung ansteigender Flanken" bezeichnet. Es speichert den Zustand des input1letzten Males durch die Schleife, vergleicht ihn mit dem Wert dieses Mal und führt die Logik aus, wenn der letzte Zustand falsch war und dieser Zustand wahr ist.

Wenn Sie keine Von Neumann-Architektur haben, ändert sich das Spiel. Zum Beispiel, wenn Sie ein FPGA in VHDL programmieren , dann wenn Sie schreiben:

outputA = input1 && input2

(... oder was auch immer die geeignete VHDL - Syntax wäre) , dann die FPGA wird tatsächlich verdrahtet , so daß input1und input2ist mit dem Eingang eines UND - Gatter geschaltet, und der Ausgang der UND - Gatter wird zu verdrahten outputA. Daher ist der Code nicht nur leicht zu verstehen, sondern wird auch parallel zu allen anderen Logikfunktionen ausgeführt und ist effizient.

Wenn es sich um eine industrielle Steuerung wie eine SPS oder ein PAC handelt, die bzw. das in einer der fünf IEC-61131-3-Sprachen programmiert ist, ist der typische Fall diese Art von Anordnung:

  1. Eingaben lesen und im Speicher ablegen
  2. Hauptprogramm ausführen
  3. Schreiben Sie die Ausgänge aus dem Speicher in die tatsächlichen Ausgänge
  4. Fahren Sie mit Schritt 1 fort

Dies ist in die Architektur des Systems integriert. Sie müssen also nur schreiben:

outputA = input1 && input2

... und es wird in einer Endlosschleife ausgeführt.

Es gibt auch Unterbrechungsroutinen in diesen Maschinen. Dies entspricht eher der Unterstützung auf Hardwareebene für den whenOperator, über den Sie sprechen. Der Hardware-Interrupt dient zum Ausführen von Code für ein externes Ereignis. Wenn beispielsweise eine Netzwerkkarte angibt, dass Daten warten, muss der Prozessor diese Daten normalerweise sofort lesen, da sonst der Pufferplatz knapp wird. Für die Häufigkeit, mit der Sie einen echten Hardware-Interrupt einbinden müssen, bezweifle ich jedoch, dass die Angabe eines Sprachschlüsselworts dafür sinnvoll ist. Sie wären auf CPU-Eingangspins beschränkt, und es sieht so aus, als wollten Sie den internen Programmstatus testen.

In einer traditionellen Sprache (ohne eine enge Schleife, die unendlich läuft) müssen Sie also die Frage stellen: "Wann wird der Evaluierungscode ausgeführt?"

Wenn du schreibst:

when A do
    launchNukes()

... und wenn Aes sich um einen beliebigen booleschen Ausdruck handelt, woher wissen Sie, wann Sie diesen Ausdruck neu bewerten müssen? Eine naive Implementierung würde bedeuten, dass Sie sie nach jedem einzelnen Speicherschreiben neu auswerten müssen. Sie könnten denken, dass Sie es eingrenzen können, aber bedenken Sie Folgendes:

when systemTime > actionTime do
    launchNukes()

Beachten Sie, dass systemTimesich dies immer ändert (jedes Mal, wenn Sie es lesen, erhalten Sie eine andere Nummer). Dies bedeutet, dass der bedingte Teil aller Ihrer whenKlauseln fortlaufend neu bewertet werden muss. Das ist fast unmöglich (und überlegen Sie sich kurz, was passiert, wenn Ihr bedingter Ausdruck Nebenwirkungen hat!)

Fazit

Sie können eine whenAnweisung (wie Sie sie beschreiben) nur in einer Architektur haben, die auf einer Endlosschleife basiert, in der das Hauptprogramm ausgeführt wird. Anschließend werden die whenAnweisungen ausgeführt, wenn die Bedingungen in dieser Schleife von false auf true geändert wurden. Während diese Architektur in eingebetteten und industriellen Geräten üblich ist, ist sie in allgemeinen Programmiersprachen nicht üblich.

Scott Whitlock
quelle
3

Die Sprache AspectJ verfügt über ein Join-Point-Modell, eine Lösung für genau diese Situation.

Ein Join-Point in AspectJ ist ein dynamisches Ereignis in einem Java-Programm, das bei der Ausführung des Programms auftritt. Beispielhafte Verknüpfungspunkte sind: (1) Eine Methode wird aufgerufen; (2) Eine Methode wird ausgeführt; (3) Ein Konstruktor wird aufgerufen; (4) Ein Konstruktor wird ausgeführt; (5) Ein Feld wird gesetzt; oder (6) Auf ein Feld wird zugegriffen.

Sie können dann Sätze dieser Verbindungspunkte erstellen, die als Punktschnitte bezeichnet werden. Punktschnitte können dann auf die übliche satztheoretische Weise verbunden, ergänzt und geschnitten werden. Andere Punktschnitte können von den Werten / Variablentypen abhängig gemacht werden (z. B. "nur wenn x positiv ist", "nur wenn der eingestellte Wert eine Unterklasse dieses Typs ist") und basieren auf dem Programmstatus ("wann") Diese Methode wird aufgerufen, jedoch nur, wenn sich diese andere Methode auf dem Stapel dieses Threads befindet (was bedeutet, dass diese Methode sie indirekt aufgerufen hat).

Sobald Sie alle diese Punkte haben, die Ereignisse im Programm beschreiben, können Sie AspectJ verwenden, um diese Ereignisse mitzuteilen . Sie können wählen, ob Sie etwas tun möchten, bevor das Ereignis eintritt ( beforeBeratung), nachdem das Ereignis eintritt ( afterBeratung) oder stattdessen das Ereignis eintritt ( aroundBeratung).

AroundRatschläge sind besonders hilfreich, wenn Sie Ihren Programmen Caching hinzufügen möchten: Wenn eine Methode ausgeführt wird, prüfen Sie in einer Tabelle, ob dieselbe Berechnung bereits durchgeführt wurde, und verwenden Sie in diesem Fall die zwischengespeicherte Version. Mit AspectJ ist es so leicht und aussagekräftig, dass Sie solche Caching-Experimente an Hunderten von verschiedenen Punkten in Ihrem Code durchführen können, um herauszufinden, ob und wo Caching Mehrwert bringt.

Viele Leute außerhalb der aspektorientierten Programmierung glauben, dass es bei AOP hauptsächlich um "Protokollierung" geht. Sie können AspectJ verwenden, um die Protokollierung zu handhaben, und es funktioniert ganz gut ("In dieser Protokolldatei aufzeichnen, wann alle öffentlichen Methoden in diesem Paket aufgerufen werden und welche Ergebnisse / Fehlerergebnisse sie haben"). Aber AspectJ hat noch viel mehr zu bieten, einschließlich eines cleveren Tricks zur Simulation des dynamischen Bereichs namens Wurmlochmuster [siehe Folie 23 und folgende].

Außerhalb von AOP sprechen Sie auch von ereignisbasierter Programmierung, zu der auch das Observer-Pattern gehört. Der Unterschied zwischen den Lösungen ist: (1) wie der Zustand erfasst wird; (2) wenn die Bedingung ausgedrückt wird; und (3) wie der auszuführende Code an das Ereignis gebunden ist.

Macneil
quelle
2

Wie man Notify / Wait benutzt , scheint ungefähr so zu sein:

Wir haben erwähnt, dass der Java-Wartemechanismus / Benachrichtigungsmechanismus im Wesentlichen eine Möglichkeit ist, zwischen Threads zu kommunizieren. Kurz gesagt lautet die Idee wie folgt:

  • Ein oder mehrere Threads warten auf ein Signal.
  • Ein anderer Thread kommt und benachrichtigt die wartenden Threads (dh "weckt sie auf" mit dem Signal).

Abhängig vom Kontext gibt es einige Strukturen, die nah beieinander liegen können, aber Sie müssen Ihre Frage wirklich klären.

Es gibt auch eine "when" -Anweisung in XSLT :

Das Element wird verwendet, um eine Vorgehensweise basierend auf einer Reihe von Tests zu bestimmen. Jeder Test wird in einem Element durchgeführt. Wenn ein Test erfolgreich ist, wird der Body des Elements ausgeführt. Wenn keine Tests fehlschlagen, kann ein Element verwendet werden, um eine Standardaktion anzugeben:


Das XSLT "when" ist eine bedingte Anweisung, eher ein Schalter als ein if. Der Kontext dessen, was in der Ausgangsfrage mit einem "Wann" gemeint war, war jedoch nicht wirklich klar.

Ich verwende XSLTs ziemlich oft im Sitecore CMS, wo ich für die Präsentation von Inhalten arbeite, damit sie in einigen Fällen in einer GUI-Umgebung verwendet werden können.

JB King
quelle
Das XSLT klingt eher nach einem if, obwohl es nicht der prozedurale Typ ist, den ifSie in Programmiersprachen finden würden. (Ich betrachte XSLT eher als eine bestimmte Datenverarbeitungssprache als eine übliche Programmiersprache. Ich sehe nicht, dass Sie eine Desktop-GUI mit XSLT erstellen.)
Marjan Venema,
2

Was Sie verlangen, heißt Reaktive Programmierung .

Es ist ein Programmierparadigma, bei dem die Variablen den ihnen zugewiesenen Ausdruck kennen und bei jeder Änderung einer Komponente des Ausdrucks die Variable mit einer Neubewertung des Ausdrucks reagiert und möglicherweise andere ähnliche Neubewertungen in der Abhängigkeitskette auslöst .

In der Regel wird dieses reaktive Verhalten durch die geschickte Verwendung von Beobachtermustern erreicht, bei denen sich ein reaktiver Wert als Zuhörer für eine Reihe von Ereignissen registriert, die die Neubewertung des Werts auslösen.

Nach meinem besten Wissen gibt es keine Programmiersprache, die ausschließlich reaktives Programmieren unterstützt, aber es gibt viele Bibliotheken in vielen Sprachen, die die Vorteile des reaktiven Programmierens auf die eine oder andere Weise bieten.

Die meisten Datenbindungs- Frameworks können als Implementierungen der reaktiven Programmierung betrachtet werden .

Es gibt ein nettes Papier mit dem Titel " Deprecating the observer pattern ", das wahrscheinlich viel besser erklären wird als ich jemals könnte, worum es bei der reaktiven Programmierung geht und was eine Implementierung über die bereits vorhandenen Techniken hinaus bieten würde.

Roland Tepp
quelle
Eine der besten Antworten auf meine Frage. Tolles Papier.
WindScar
1
Fühlen Sie sich frei, um es als "akzeptiert" zu markieren (zwinkert, zwinkert, nickt, nickt)
Roland Tepp
Ich wollte das posten, aber glücklich hast du mich geschlagen und eine viel bessere Antwort geschrieben als ich. Reaktives Programmieren ist großartig (und eine großartige Möglichkeit, Benutzeroberflächen in funktionalen Sprachen zu erstellen), aber ein wenig esoterisch.
Tikhon Jelvis
1
@ RolandTepp Schamlose Eigenwerbung, was? Ich bewundere das an dir. +1
Neil
0

Lisp (und seine vielen Dialekte, einschließlich Schema) hat es:

(when (> 2 1) 'do-something)

wertet aus do-somethingund:

(when nil 'other-thing)

bewertet zu niloder sein Äquivalent.

laut und klar
quelle
2
Lisps whenist eher ein Wenn, nicht das vom OP versehentlich beschriebene Beobachtermuster.
ocodo
0

Ich kenne eine solche Aussage nur zur Fehlerbehandlung. Zum Beispiel BASICs ON ERROR ...oder SQL * PLUSsWHENEVER SQLERROR ...

Für arbitratische Bedingungen wäre entweder ein äußerst geschickter Compiler oder eine ziemlich teure Art von Brute Force erforderlich (Prüfung nach jeder Anweisung), um den genauen Zeitpunkt zu erfassen, zu dem die Bedingungen erfüllt sind.

user281377
quelle
0

Es ist eine Funktion von Datenflusssprachen wie Hardwarebeschreibungssprachen (Verilog und VHDL).

Davon abgesehen kann ich mir Ada und seinen Ausnahmebehandlungsmechanismus vorstellen: Ein Ausnahmebehandlungsroutine wird ausgelöst, eine Ausnahme wird ausgelöst when.

mouviciel
quelle
0

Es hört sich so an, als ob Sie nach Bedingungsvariablen suchen , nach Dingen, die es Threads ermöglichen, zu schlafen, bis ein Prädikat wahr wird.

Boost implementiert sie für C ++, die Apache Portable Runtime implementiert sie für C. In Common Lisp verwenden Sie bordeaux-thread's make-condition-variable.

Frank Shearar
quelle
Können Sie den Teil der Boost-Bibliothek benennen, der für die Implementierung verantwortlich ist?
WindScar
0

Wenn du Drools als eine Sprache ansiehst, dann ja.

Ein Beispiel:

rule "Rule 08 - Debit"
when
    AccountingPeriod( $start : start, $end : end )
    $cashflow : AllocatedCashflow( $account : account, $date : date <= $end, $amount : amount, type==TypedCashflow.DEBIT )
    not AccountingPeriod( start < $start)
then 
    $account.setBalance($account.getBalance()-$amount);
    retract($cashflow);
end
ptyx
quelle
0

Perl 6 kann direkt mit Signalen umgehen, indem es Folgendes verwendet tap:

signal(SIGINT).tap: {
    note "Took { now - INIT now } seconds.";
    exit;
}

for 0, 1, *+* ... * {
    sleep 0.5;
    .say;
}

Während Powershell mit einer Run-Schleife mit einem try / finally-Block umgehen kann:

$Start_Time = (Get-date).second
Write-Host "Type CTRL-C to Terminate..."
$n = 1
Try
{
    While($true)
    {
        Write-Host $n
        $n ++
        Start-Sleep -m 500
    }
}
Finally
{
    $End_Time = (Get-date).second
    $Time_Diff = $End_Time - $Start_Time
    Write-Host "Total time in seconds"$Time_Diff
}

wie erwartet mit trap:

package require Expect

proc sigint_handler {} {
    puts "elapsed time: [expr {[clock seconds] - $::start_time}] seconds"
    set ::looping false
}

trap sigint_handler SIGINT

set start_time [clock seconds]
set n 0
set looping true
while {$looping} {
    puts [incr n]
    after 500
}

Verweise

Paul Sweatte
quelle
0

Es ist lange her, seit ich diese angeschaut habe, also könnte ich mich gut irren.

Wie ich mich erinnere, hatten PL / I und BASIC beide "ON" -Anweisungen. In PL / I lautete das Konzept "ON DO". In BASIC war es "ON", wobei die Anweisung normalerweise ein GOSUB war. In beiden Sprachen wurden die zugehörigen Anweisungen ausgeführt, wenn die angegebene Bedingung erfüllt wurde.

Das würdest du heute nicht wollen. Der Compiler muss im Grunde genommen eine Menge Arbeit leisten, um herauszufinden, wo / wann die Bedingung eintreten könnte, damit er zu diesem Zeitpunkt einen Test generieren kann. Sobald Sie im zugehörigen Handler sind, wissen Sie nicht wirklich, woher Sie gekommen sind. Sie müssen also herausfinden, was passiert ist, um dorthin zu gelangen, und Sie möchten wahrscheinlich nicht dorthin zurückkehren, woher Sie gekommen sind.

John R. Strohm
quelle
0

Sie könnten einen Blick auf die OPS5- Sprache werfen . Seine Programme sind als eine Reihe von Bedingungen geschrieben. Wenn eine Bedingung erfüllt ist, wird die entsprechende Aktion ausgeführt. Die Aktionen können den Status ändern, wodurch andere Bedingungen erfüllt werden können. Das whenSchlüsselwort wird zwar nicht verwendet , es funktioniert jedoch im Wesentlichen, indem Aktionen ausgeführt werden, "wenn" eine Bedingung erfüllt ist. Von hier :

Ein OPS5-Programm besteht aus einem Deklarationsteil, in dem grundlegende Datenkonstrukte definiert werden, gefolgt von einem Produktionsteil, in dem Regeln für die Bearbeitung der Daten festgelegt werden.

OPS5-Programme werden ausgeführt, indem Arbeitsspeicherelemente mit Regeln im Produktionsspeicher abgeglichen werden und die dominanteste Regel ausgeführt wird, die abgeglichen wird. Der Match-Select-Execute-Zyklus wird fortgesetzt, bis das Programm explizit angehalten wird oder bis keine Regeln mehr mit dem Arbeitsspeicher abgeglichen werden können.

Als ich Anfang der 90er Jahre an der Universität war, musste ich ein einfaches Textabenteuer in dieser Sprache schreiben. Es war interessant, aber ich bin mir nicht sicher, wie nützlich es für die meisten Desktop- oder mobilen Aufgaben sein würde. Dies kann jedoch in einer Backend-Umgebung sinnvoll sein.

user1118321
quelle
-1

In den meisten OOP-Sprachen ist es möglich, einen zusätzlichen Thread zu erzeugen. Geben Sie dies als Kontext an:

    while (!value)
{
}

//Execute code
Derek
quelle
-1

Nun, Sie könnten eine Reihe paralleler Threads schreiben, von denen jeder nach seinem jeweiligen Zustand fragt. Ich nehme an, das wäre eine ziemlich leistungsschwache Anwendung, aber es ist möglich.

Stephen Gross
quelle