Czy istnieje coś takiego jak stwierdzenie „kiedy”? [Zamknięte]

12

Czy istnieje język lub funkcja języka, która może obsługiwać przypadki „kiedy”? Czy za każdym razem, gdy spełniony zostanie jakiś warunek, w dowolnym zakresie lub kontekście, można podać dodatkowy kod do wykonania?

Zauważ, że różni się to od prostego if, który musi mieć określony zakres i być wyraźnie zapisany. To kiedy klauzula byłaby prawie jak ifta stosowana w każdym przypadku podczas wykonywania programu po nim.

Macneil
źródło
1
SQL Server: select case table1.col1 when 1 then 'Y' else 'N' end as col1_yn from .... Ponadto: msdn.microsoft.com/en-us/library/dd233249.aspx Zasadniczo zrobiłbym wyszukiwanie „kiedy” za pomocą wyszukiwania kodu Google.
Job
5
@Job: To klauzula, a nie stwierdzenie.
Ben Voigt
2
Masz na myśli jak w Verilog?
dan04
2
Potrzebuje więcej opisu ... bardzo szerokie pytanie.
WernerCD
2
Pytanie jest omawiane tutaj na meta.
Adam Lear

Odpowiedzi:

25

Twoje pytanie nie jest jasne, ale wzór Observer wydaje się być tym, czego szukasz http://en.wikipedia.org/wiki/Observer_pattern

Victor Hurdugaci
źródło
1
Tak, to, o co prosiłem, wydaje się dla tego rodzimą implementacją. Chciałbym również wskazać na interesujący artykuł na temat programowania reaktywnego, zamieszczony poniżej, „deprecjonujący wzorzec obserwatora” (bez linku, CTRL + F it). Instrukcja when, teoretycznie, uruchamiałaby blok kodu, ilekroć podczas wykonywania programu zostanie spełniony warunek - bez względu na to, jak to jest zaimplementowane - i ułatwiłby pracę przynajmniej mi, który zamiast tego będzie musiał zaimplementować wzór obserwatora przeze mnie.
WindScar,
15

Jeśli chodzi o składnię, wiele języków ma whensłowo kluczowe, ale nie znam żadnego języka, który używa go w sposób opisany przez Ciebie.

Wzorzec „kiedy pojawia się X, zrób Y” jest swego rodzaju rdzeniem programowania zorientowanego na aspekty: zamiast definiować przepływ liniowy, zaczepiasz procedury obsługi w określonych warunkach (inaczej „subskrybowanie” „zdarzenia”). Ten rodzaj programowania jest popularny w aplikacjach GUI, w których podstawową procedurą programu jest dyspozytor zdarzeń.

Niektóre języki mają rozbudowane funkcje składniowe zapewniające takie mechanizmy poprzez konstrukcje językowe; przykładem może być C # z jego delegatami i wydarzeniami:

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

Inne języki używają konstrukcji OOP (wzorzec obserwatora, detektory zdarzeń itp.; Przykład w Javie (moja Java jest nieco zardzewiała, więc edytuj):

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

Jeszcze innym podejściem jest używanie zwykłych starych wywołań zwrotnych. Przykład w javascript:

var btnOK = $('btnOK');
btnOK.click(handleOKClick);
tdammers
źródło
15

Nikt jeszcze nie wspomniał o COMEFROM od INTERCAL :

COMEFROM był początkowo widoczny na listach instrukcji języka asemblera (jako „CMFRM”). Został on opracowany w artykule Datamation autorstwa R. Lawrence'a Clarka w 1973 roku, napisanym w odpowiedzi na list Edsgera Dijkstry Go To Statement Za szkodliwy. COMEFROM został ostatecznie zaimplementowany w wariancie C-INTERCAL ezoterycznego języka programowania INTERCAL wraz z jeszcze bardziej niejasnym „obliczonym COMEFROM”. Były też propozycje Fortranu dotyczące „przypisanego COME FROM” i słowa kluczowego „DONT” (w celu uzupełnienia istniejącej pętli „DO”).

1 kwietnia 2004 r. Richie Hindle opublikował implementację GOTO i COMEFROM dla języka programowania Python. Mimo że została wydana w prima aprilis i nie jest przeznaczona do poważnego użytku, składnia jest poprawna, a implementacja w pełni działa.

Matthieu
źródło
7
... a ty musiał ją zepsuć! :-)
Stephen C
2
O rly?
Ben Voigt
2
@BenVoigt: Twoja odpowiedź w momencie publikacji nie zawierała „Intercal” ani „COMEFROM”.
DeadMG
2
@DeadMG: Moja odpowiedź zawierała „ en.wikipedia.org/wiki/COMEFROM ” od pierwszej wersji.
Ben Voigt
2
@BenVoigt: To się nie liczy.
DeadMG
6

Język Tcl ma ślady na zmiennych, które pozwalają na wykonanie dowolnego kodu za każdym razem, gdy zmienna jest ustawiona (lub czytana lub usuwana, ale jest to mniej ważne tutaj). Ten dowolny kod może z łatwością obejmować ocenę wyrażenia i wykonanie jakiegoś kodu, jeśli się on trzyma. Głównym ograniczeniem jest to, że chociaż można to zrobić w przypadku zmiennych lokalnych, nie jest to na ogół bardzo przydatne, ponieważ mają one zwykle bardzo krótki okres użytkowania, więc takie rzeczy są zwykle ograniczone do zmiennych globalnych i zmiennych przestrzeni nazw. (Tcl nie ma zamknięć.)

Ale jeśli to robisz, powinieneś być ostrożny. Chociaż oficjalnie nie masz problemów z ponownym uruchomieniem (śledzenie jest wyłączone na czas wykonywania ciała), nadal jest to świetny sposób na napisanie bardzo niejasnego kodu i spowodowanie dużego zamieszania. Jest to również naprawdę okropny pomysł, aby używać go ze zmienną pętli (inną niż do debugowania), ponieważ wydajność może być dość znacząca.


Przykład (oparty na kodzie z połączonej strony podręcznika powyżej) ilustruje.

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

Od tego momentu, za każdym razem, gdy $fooalbo stanie $barsię nową liczbą całkowitą, $foobarstaje się produktem tych dwóch. Automatycznie.


Tcl pozwala również na konfigurowanie kodu do uruchamiania na innych rodzajach wyzwalaczy, takich jak wykonywanie poleceń, usuwanie poleceń, timery, udostępnianie danych w gniazdach itp. Po dodaniu biblioteki Tk jest to rozszerzenie o cały duży zestaw zdarzeń GUI. Prawdą jest, że Tcl jest bardzo silnie zorientowanym na zdarzenia językiem (nawet jeśli można łatwo napisać kod, który nigdy nie korzysta z żadnej z tych funkcji).

Donal Fellows
źródło
4

Coś jak obsługa zdarzeń?

zamiast func () obsługuje zdarzenia

mówisz, kiedy wydarzenie działa

A może oddzwanianie na konkretnej zmiennej?

Akash
źródło
Zdecydowanie brzmi jak wydarzenie.
Ton Plomp,
4

Tak, w Perlu jest takie słowo kluczowe, jak modyfikator instrukcji:

say 'Well done!'        when 'A';

Jest to również część instrukcji switch:

given ($foo) {
    when (/^abc/) { $abc = 1; }
    when (/^def/) { $def = 1; }
    when (/^xyz/) { $xyz = 1; }
    default { $nothing = 1; }
}
rev Ubiquité
źródło
5
Nie znam Perla, ale to „kiedy” dla mnie wygląda bardziej jak „jeśli” ... Myślę, że pytanie to oznacza „kiedy <event> <action>” typu „when”.
ShdNx
1
Pachnie mi jak switchoświadczenie. (Mosiądzem pokrętła na nim, ale potem znowu jest Perl ...)
Donal Fellows
W rzeczywistości jest caseto switchstwierdzenie. Tak jak w Adzie.
mouviciel
4

Czy to ( COMEFROMoświadczenie opisane na Wikipedii) się liczy?

Podsumowanie:

COMEFROM jest mniej więcej przeciwieństwem GOTO, ponieważ może przenieść stan wykonania z dowolnego dowolnego punktu kodu do instrukcji COMEFROM. Punkt w kodzie, w którym następuje transfer stanu, jest zwykle podawany jako parametr parametru COMEFROM. To, czy transfer nastąpi przed instrukcją w określonym punkcie transferu, czy po niej, zależy od używanego języka. W zależności od używanego języka wiele obiektów COMEFROM odnoszących się do tego samego punktu wyjścia może być niepoprawnych, być niedeterministycznych, być wykonywanych z pewnego rodzaju określonym priorytetem, a nawet wywoływać wykonywanie równoległe lub w inny sposób współbieżne, jak widać w wątku intercal.

Ben Voigt
źródło
6
Widzę skąd pochodzisz.
Pubby
6
-1 dla linku bez streszczenia; linkrot może się zdarzyć.
Hugo
5
@Ben - Niezależnie od tego Twoja odpowiedź byłaby znacznie lepsza, gdybyś chciał napisać nieco więcej niż 3 słowa.
BlackJack
3
@BenVoigt: w takim przypadku mógłbyś po prostu wkleić cały link zamiast ukrywać go za „tym”.
Marjan Venema
1
@BenVoigt: Chodziło mi o to, że jeśli wkleiłeś cały link zamiast ukryć go za „tym”, wyszukiwane słowa byłyby natychmiast widoczne w tekście twojej odpowiedzi, a nie tylko po najechaniu kursorem na link… Ponadto akurat zgadzam się z BlackJackiem i Hugo, że odpowiedź, która jest głównie linkiem, powinna przynajmniej zawierać krótkie podsumowanie tego, co można tam znaleźć. Pomaga upewnić się, że StackExchange może stać na własnych nogach, nawet jeśli łącze gnije.
Marjan Venema
3

Czy szukasz języka z instrukcją synchroniczną lub asynchroniczną when?

Brzmi jak wzorzec zdarzenia (/ subskrypcja / oddzwanianie).

Na przykład

conditionOwner.Condition += listener.WhenCondition

Ilekroć właściciel warunku powiadomi, że warunek miał miejsce, detektor wykona WhenCondition ().

Można użyć wzorca powiązania z konwerterem, który sprawdza stan kilku zmiennych wejściowych (przy zmianie) i oblicza warunek, a następnie przypisuje właściwość wejściową detektora do wyjścia i działa po zmianie tego wejścia.

Jeśli chodzi o języki, na przykład .NET (tj. C #) ma wbudowane subskrypcje synchroniczne (zdarzenia), a jego rozszerzenia reaktywne (RX) dodają subskrypcje asynchroniczne.

Danny Varod
źródło
3

Opis brzmi jak wyzwalacz bazy danych, którego zadaniem jest oczekiwanie na określony scenariusz, a następnie wykonanie.

Z Wikipedii:

Wyzwalacz bazy danych to kod proceduralny, który jest automatycznie wykonywany w odpowiedzi na określone zdarzenia w określonej tabeli lub widoku w bazie danych. Wyzwalacz służy głównie do zachowania integralności informacji w bazie danych. Na przykład po dodaniu nowego rekordu (reprezentującego nowego pracownika) do tabeli pracowników należy utworzyć nowe rekordy również w tabelach podatków, urlopów i wynagrodzeń.

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

użytkownik1249
źródło
3

Mówisz o mniejszej składni niż strukturze . Tak naprawdę można mieć tylko taką wheninstrukcję w systemie, który wykonuje skończoną ilość logiki, a następnie wykonuje wheninstrukcje, następnie zapętla się i wykonuje logikę ponownie, kontynuując w nieskończonej pętli.

Na przykład programowanie w systemie Windows jest zazwyczaj „oparte na zdarzeniu”. Subskrybowanie Clickzdarzenia przycisku w zasadzie oznacza „zrób to po kliknięciu”. Jednak pod maską działa pętla przetwarzania wiadomości. System Windows wysyła komunikat do aplikacji, gdy użytkownik kliknie przycisk, a pętla przetwarzania komunikatów w aplikacji uruchamia odpowiednią procedurę obsługi zdarzeń.

Jeśli korzystasz ze zdarzeń, na przykład w C #, możesz to zrobić bez pętli komunikatów, ale ograniczenie polega na tym, że musisz zadeklarować zdarzenie z wyprzedzeniem, więc nie możesz napisać wheninstrukcji biblioteki , która będzie obserwować każdy rodzaj stan. Musisz poczekać na określone wydarzenie.

Aby uzyskać takie zachowanie w architekturze Von Neumann, musisz uruchomić jakąś nieskończoną pętlę, która za każdym razem sprawdza wszystkie warunki za pośrednictwem pętli z uruchomionym odpowiednim kodem, jeśli jest to właściwe. Wewnętrznie otrzymujesz dużą listę if/ thenlub switchwyciągów. Większość aplikacji komputerowych i programistów internetowych zwymiotowałaby, gdyby zobaczyli taką konstrukcję, więc jest to naprawdę smaczne, jeśli otoczysz ją jakimś cukrem syntaktycznym, takim jak model zdarzeń Windows (nawet jeśli to się dzieje pod maską).

Z drugiej strony, jeśli spojrzysz na dziedzinę oprogramowania wbudowanego, menedżerów w czasie rzeczywistym lub kontrolerów przemysłowych, ten model programowania jest bardzo powszechny. Na przykład, jeśli masz program działający w czasie rzeczywistym, możesz chcieć wyrazić:

outputA = input1 && input2

Kod jest prosty do zrozumienia (ponieważ jest deklaratywny). Aby jednak działało, musisz wykonać go w ciasnej pętli. Ponownie oceniasz za outputAkażdym razem przez pętlę. Wielu programistów stacjonarnych lub internetowych nie spodobałoby się to, ponieważ jest nieefektywne. Dla nich jedyną porą, którą powinieneś ponownie ocenić, outputAjest czas input1lub input2zmiany. Wolą zobaczyć coś, co opisujesz:

when input1 changes
    evaluateOutputA()

when input2 changes
    evaluateOutputA()

evaluateOutputA()
    outputA = input1 && input2

Teraz, jeśli tego właśnie chcesz (a osobiście nie wolę tego pomysłu), a twoim celem jest wydajność, nadal musisz zadać sobie pytanie, co robi procesor pod maską. Oczywiście nadal działa pętla, która za każdym razem porównuje stany wejściowe z poprzednimi stanami wejściowymi i wykonuje odpowiedni kod przy każdej zmianie. Tak naprawdę jest mniej wydajny, trudniejszy do odczytania i trudniejszy w utrzymaniu.

Z drugiej strony, jeśli praca, którą musisz wykonać, gdy input1zmiany są znaczące, twoja whenklauzula może mieć sens. W sterownikach tego typu instrukcje nazywane są „wykrywaniem zbocza narastającego”. Zapisuje stan input1ostatniej chwili przez pętlę, tym razem porównuje ją z wartością i wykonuje logikę, jeśli ostatni stan był fałszywy, a ten stan jest prawdziwy.

Jeśli nie masz architektury von Neumanna, gra się zmieni. Na przykład, jeśli programujesz FPGA w VHDL , wtedy kiedy piszesz:

outputA = input1 && input2

(... lub cokolwiek odpowiedniej składni VHDL będzie), a następnie FPGA faktycznie pobiera się w taki sposób, przewodowy input1i input2są podłączone do wejścia elementu I, a wyjście z bramki AND jest podłączony do outputA. Kod jest więc nie tylko łatwy do zrozumienia, ale także wykonywany równolegle z całą inną logiką i jest wydajny.

Gdy mówisz o sterowniku przemysłowym, takim jak PLC lub PAC, zaprogramowanym w jednym z pięciu języków IEC-61131-3, typowym przypadkiem jest taki układ:

  1. Odczytaj dane wejściowe i zapisz w pamięci
  2. Uruchom program główny
  3. Zapisuj wyjścia z pamięci na rzeczywiste wyjścia
  4. Przejdź do kroku 1

Jest to wbudowane w architekturę systemu, więc oczekuje się, że napiszesz:

outputA = input1 && input2

... i zostanie wykonany w ciągłej pętli.

Istnieją również procedury przerwania w tych maszynach. Są one bardziej jak wsparcie na poziomie sprzętowym dla whenoperatora, o którym mówisz. Przerwanie sprzętowe jest sposobem wykonywania kodu na zdarzenie zewnętrzne. Na przykład, gdy karta sieciowa mówi, że czekają na nią dane, procesor zwykle musi natychmiast odczytać te dane lub zabraknie miejsca w buforze. Jednak z uwagi na to, ile razy trzeba złapać prawdziwe przerwanie sprzętowe, wątpię, czy warto podać słowo kluczowe dla tego języka. Będziesz ograniczony do pinów wejściowych procesora i wygląda na to, że chcesz przetestować wewnętrzny stan programu.

Tak więc w tradycyjnym języku (bez ciasnej pętli, która działa nieskończenie), musisz zadać pytanie „kiedy działa kod ewaluacyjny”?

Jeśli napiszesz:

when A do
    launchNukes()

... i zakładając A jest to dowolne wyrażenie boolowskie, skąd wiesz, kiedy ponownie ocenić to wyrażenie? Naiwna implementacja oznaczałaby konieczność ponownej oceny po każdym zapisie w pamięci. Możesz pomyśleć, że możesz to zawęzić, ale rozważ to:

when systemTime > actionTime do
    launchNukes()

Zauważ, że systemTime zawsze się zmienia (za każdym razem, gdy ją czytasz, dostajesz inny numer). Oznacza to, że część warunkowa wszystkich whenklauzul musi być ciągle oceniana. To prawie niemożliwe (i zastanów się przez chwilę, co się stanie, jeśli wyrażenie warunkowe ma skutki uboczne!)

Wniosek

Możesz mieć tylko wheninstrukcję (tak jak to opisujesz) w architekturze opartej na nieskończonej pętli, która uruchamia główny program, a następnie wykonuje wheninstrukcje, jeśli warunki w tej pętli zmieniły się z false na true. Chociaż ta architektura jest powszechna w urządzeniach wbudowanych i przemysłowych, nie jest powszechna w językach programowania ogólnego przeznaczenia.

Scott Whitlock
źródło
3

Język AspectJ ma model Join-Point, który jest jednym rozwiązaniem do obsługi dokładnie tego rodzaju sytuacji.

Punkt łączenia w AspectJ to dynamiczne zdarzenie w programie Java, które występuje podczas jego wykonywania. Przykładowe punkty łączenia to: (1) Wywoływana jest metoda; (2) Metoda jest wykonywana; (3) Wywoływany jest konstruktor; (4) Konstruktor jest wykonywany; (5) Pole jest ustawione; lub (6) Dostęp do pola.

Następnie można utworzyć zestawy tych punktów łączenia, zwanych punktami cięcia. Punkty cięcia można następnie łączyć, uzupełniać i przecinać w zwykły sposób teorii zbiorów. Inne cięcia punktowe mogą być uwarunkowane wartościami / typami zmiennych (np. „Tylko gdy x jest dodatnia”, „tylko gdy ustawiana wartość jest podklasą tego typu”) i na podstawie stanu programu („kiedy ta metoda jest wywoływana, ale tylko wtedy, gdy ta inna metoda znajduje się na stosie tego wątku [co oznacza, że ​​ta metoda pośrednio ją wywołała] ").

Gdy wszystkie te skróty punktowe opisują zdarzenia w programie, możesz użyć AspectJ, aby doradzić tym zdarzeniom. Możesz wybrać zrobienie czegoś przed wydarzeniem ( beforerada), po wydarzeniu ( afterrada) lub zamiast zdarzenia ( aroundrada).

Aroundrada jest szczególnie pomocna przy dodawaniu buforowania do programów: Po wykonaniu jakiejś metody, poszukaj w tabeli, czy to samo obliczenie zostało już wykonane, a jeśli tak, skorzystaj z wersji buforowanej. Dzięki AspectJ jest tak lekki i wyrazisty, że możesz przeprowadzać takie eksperymenty buforowania na setkach różnych punktów w kodzie, aby sprawdzić, czy i gdzie buforowanie dodaje wartości.

Wiele osób spoza programowania aspektowego uważa, że ​​AOP polega głównie na „logowaniu”. Możesz użyć AspectJ do obsługi rejestrowania, i robi to całkiem dobrze („zapisz w tym pliku dziennika, gdy zostaną wywołane wszystkie metody publiczne w tym pakiecie i jakie były ich wyniki / wyniki błędów”). Ale AspectJ oferuje o wiele więcej, w tym sprytną sztuczkę do symulacji zakresu dynamicznego zwaną Wzorem Worm Hole [patrz slajd 23 i następne].

Poza AOP mówisz także o programowaniu opartym na zdarzeniach, które obejmuje [jak zauważyli inni] wzorzec obserwatora. Różnica między rozwiązaniami polega na: (1) sposobie wykrywania stanu; (2) jeżeli warunek jest wyrażony; oraz (3) sposób, w jaki kod do wykonania jest powiązany ze zdarzeniem.

Macneil
źródło
2

Jak korzystać z funkcji Powiadom / Czekaj wydaje się być blisko:

Wspominaliśmy, że mechanizm oczekiwania / powiadamiania Java jest zasadniczo sposobem komunikacji między wątkami. Krótko mówiąc, pomysł jest następujący:

  • jeden lub więcej wątków czeka na sygnał;
  • pojawia się inny wątek i powiadamia oczekujące wątki (tj. „budzi go / budzi” sygnałem).

W zależności od kontekstu istnieją pewne struktury, które mogą być do tego bliskie, ale naprawdę musisz wyjaśnić swoje pytanie.

Istnieje również instrukcja „when” w XSLT :

Element służy do określenia jednego kierunku działania na podstawie serii testów. Każdy test jest wykonywany wewnątrz elementu. Jeśli test się powiedzie, wykonywana jest bryła elementu. Jeśli żadne testy nie zakończą się niepowodzeniem, można użyć elementu do określenia domyślnej akcji:


XSLT „when” jest instrukcją warunkową, bardziej przypomina przełącznik niż if. Jednak kontekst tego, co oznaczało „kiedy” w początkowym pytaniu, nie był tak naprawdę dobrze wyjaśniony.

Dość często używam XSLT w Sitecore CMS, w którym pracuję nad prezentowaniem treści, aby w niektórych przypadkach można było z niej korzystać w środowisku GUI.

JB King
źródło
XSLT, gdy brzmi bardziej jak if, chociaż nie jest to typ proceduralny, ifktóry można znaleźć w językach programowania. (Widzę XSLT bardziej jako konkretny język przetwarzania danych niż zwykły język programowania - nie widzę, jak budujesz graficzny interfejs użytkownika za pomocą XSLT)
Marjan Venema
2

To, o co prosisz, nazywa się Programowaniem Reaktywnym .

Jest to paradygmat programowania, w którym zmienne są świadome przypisanego im wyrażenia i za każdym razem, gdy zmienia się składnik wyrażenia, zmienna reaguje poprzez ponowną ocenę wyrażenia, prawdopodobnie wyzwalając inne podobne ponowne oceny w łańcuchu zależności .

Zwykle to zachowanie reaktywne osiąga się poprzez sprytne użycie wzorca obserwatora, w którym wartość reaktywna rejestruje się jako odbiornik zestawu zdarzeń, które wyzwalają ponowną ocenę wartości.

Według mojej najlepszej wiedzy, nie istnieje język programowania, który w swoim rdzeniu obejmowałby całkowicie programowanie reaktywne, ale istnieje wiele bibliotek w wielu językach oferujących korzyści z programowania reaktywnego w taki czy inny sposób.

Większość ram wiązania danych można uznać za implementacje programowania reaktywnego .

Jest ładny artykuł zatytułowany „ Przestrzeganie wzorca obserwatora ”, który prawdopodobnie wyjaśni znacznie lepiej niż kiedykolwiek mogłem, na czym polega reaktywne programowanie i co oferuje jego implementacja ponad istniejące techniki.

Roland Tepp
źródło
Jedna z najlepszych odpowiedzi na moje pytanie. Świetny papier.
WindScar,
1
Oznacz
Już miałem to opublikować, ale szczęśliwie pobiłeś mnie i napisałeś o wiele lepszą odpowiedź, niż bym to zrobił. Reaktywne programowanie jest niesamowite (i świetny sposób na tworzenie interfejsów użytkownika w językach funkcjonalnych), ale trochę ezoteryczne.
Tikhon Jelvis,
1
@RolandTepp Bezwstydna autopromocja, co? Podziwiam to w tobie. +1
Neil
0

Lisp (i wiele dialetów, w tym Schemat) ma to:

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

ocenia do-somethingi:

(when nil 'other-thing)

ocenia nillub równorzędne.

głośno i wyraźnie
źródło
2
Lisp whenjest bardziej jak if, a nie wzór obserwatora przypadkowo opisany przez OP.
ocodo
0

Tego rodzaju stwierdzenie znam tylko do obsługi błędów. Na przykład BASIC ON ERROR ...lub SQL * PLUSWHENEVER SQLERROR ...

W przypadku dowolnych warunków wymagałoby to albo wyjątkowo sprytnego kompilatora, albo dość drogiego rodzaju brutalnej siły (sprawdź po każdym stwierdzeniu), aby uchwycić dokładny moment, w którym warunki się spełniają.

użytkownik 281377
źródło
0

Jest to funkcja języków przepływu danych, takich jak języki opisu sprzętu (Verilog i VHDL).

Poza tym mogę myśleć o Adzie i jej mechanizmie obsługi wyjątków: Program obsługi wyjątków jest wyzwalany, whenpojawia się wyjątek.

mouviciel
źródło
0

Jeśli uważasz Drools za język, to tak.

Przykład:

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
źródło
0

Perl 6 może obsługiwać sygnały w bezpośredni sposób, używając tap:

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

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

podczas gdy Powershell może obsłużyć to za pomocą pętli uruchamiania z blokiem try / wreszcie:

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

jak można się spodziewać przy użyciu 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
}

Bibliografia

Paul Sweatte
źródło
0

Minęło dużo czasu, odkąd na nie spojrzałem, więc mogłem się pomylić.

O ile pamiętam, PL / I i BASIC miały instrukcje „ON”. W PL / I koncepcja brzmiała „ON DO”. W języku BASIC było to „WŁĄCZONE”, gdzie instrukcja była zwykle GOSUB. W obu językach za każdym razem, gdy spełniony został określony warunek, powiązane instrukcje były wykonywane.

Nie chciałbyś tego dzisiaj robić. Kompilator musi w zasadzie wykonać sporo pracy, aby dowiedzieć się, gdzie / kiedy warunek może się spełnić, aby w tym momencie wygenerować test. Gdy jesteś już w powiązanym programie obsługi, tak naprawdę nie wiesz, skąd przyszedłeś, więc musisz dowiedzieć się, co się z tobą stało, i prawdopodobnie nie chcesz wracać do miejsca, z którego przyszedłeś.

John R. Strohm
źródło
0

Możesz rzucić okiem na język OPS5 . Jego programy są zapisane jako zbiór warunków. Po spełnieniu warunku wykonywana jest odpowiednia akcja. Działania mogą modyfikować stan, co może powodować spełnienie innych warunków. Chociaż nie używa whensłowa kluczowego, działa zasadniczo poprzez wykonywanie akcji „po” spełnieniu warunku. Od tutaj :

Program OPS5 składa się z sekcji deklaracji, w której zdefiniowane są podstawowe konstrukcje danych, a następnie sekcji produkcji, w której reguły manipulacji danymi.

Programy OPS5 wykonują się, dopasowując elementy pamięci roboczej do reguł w pamięci produkcyjnej i odpalając (wykonując) najbardziej dominującą, dopasowaną regułę. Cykl Match-Select-Execute trwa do momentu, aż program wyraźnie się zatrzyma lub dopóki nie można dopasować reguł do pamięci roboczej.

Musiałem napisać prostą przygodę tekstową w tym języku, kiedy byłem na uniwersytecie na początku lat 90. To było interesujące, ale nie jestem pewien, jak przydatne byłoby w przypadku większości zadań na komputerze lub urządzeniu mobilnym. Może to jednak mieć sens w środowisku zaplecza.

użytkownik1118321
źródło
-1

W większości języków OOP byłoby możliwe odrodzenie dodatkowego wątku, który ma to jako kontekst:

    while (!value)
{
}

//Execute code
Derek
źródło
-1

Cóż, możesz napisać kilka równoległych wątków, z których każdy odpytuje pod kątem odpowiedniego stanu. Przypuszczam, że byłaby to raczej mało wydajna aplikacja, ale jest to możliwe.

Stephen Gross
źródło