2013-04-01 4 views
7

Gibt es ein Symbol oder ein bekanntes Idiom für die bedingte Funktion in einem der APL-Dialekte?Bedingte Funktion in APL

Ich bin sicher, dass ich etwas vermisse, weil es so ein grundlegendes Sprachelement ist. In anderen Sprachen heißt es bedingter Operator, aber ich werde diesen Begriff hier vermeiden, weil ein APL-Operator etwas ganz anderes ist.

Zum Beispiel C und Freunde haben x ? T : F
lispelt haben (if x T F)
Python T if x else F
und so weiter hat.

Ich weiß moderne APLs haben :If und Freunde, aber sie sind zwingend notwendig, Aussagen Programmablauf zu steuern: sie keinen Wert zurückgibt, kann nicht in einem Ausdruck verwendet werden, und schon gar nicht auf Anordnungen von booleans angewandt werden. Sie haben einen ganz anderen Zweck, was bei mir in Ordnung ist.

Der einzige anständige Ausdruck, den ich einfiel eine funktionale Auswahl zu tun ist, (F T)[⎕IO+x], die nicht besonders für mich sieht eine Abkürzung oder lesbar, obwohl es wird die Arbeit getan, auch auf Arrays:

 ('no' 'yes')[⎕IO+(⍳5)∘.>(⍳5)] 
no no no no no 
yes no no no no 
yes yes no no no 
yes yes yes no no 
yes yes yes yes no 

Ich versuchte mit dem Squad einen ähnlichen Ausdruck zu finden, scheiterte aber kläglich an booleschen Arrays. Selbst wenn ich könnte, müsste es immer noch ⎕IO oder eine hardcoded 1 einbetten, was noch schlimmer ist, was die Lesbarkeit betrifft.

Bevor ich weitermachen und meine eigene if definieren und sie auf jedem Programm verwenden, das ich jemals schreiben werde, gibt es irgendeinen Canon auf diesem? Fehle ich eine offensichtliche Funktion oder einen Operator?

(Gibt es APL-Programmierer auf SO? :-)

Antwort

8

Ja, es gibt APL-Programmierer auf SO (aber nicht viele!).

Ich denke die Antwort ist, dass es keinen Standard dafür gibt.

Für eine skalare Lösung, ich "Pick" verwenden:

x⊃f t 

Während für einen Booleschen Array verwende ich die Indizierung, wie Sie oben tun:

f t[x] 

ich immer Index Ursprung Null, verwenden Sie so Es gibt keine Notwendigkeit, 1 hinzuzufügen, und die Parens werden nicht benötigt.

Wenn diese nicht einfach genug sind, müssen Sie sie mit einer Funktion namens "if" abdecken. Das wird auch das Wahre und Falsche in die vielleicht natürlichere Ordnung von t f setzen.

+0

Danke. Ich komme von einem C-Hintergrund, so dass Indexursprung bei Null sehr sinnvoll für mich ist, aber ich wollte nicht gegen den "APL-Weg" gehen – Tobia

+0

Tonnen von Iversons Papieren nehmen durchweg den Nullpunkt an. Es ist eine gute Wahl, wenn es vereinfacht, was Sie tun. –

8

Das Problem mit diesen:

(f t)[x] 
x⌷f t 
x⊃f t 

ist, dass sowohl t und f ausgewertet bekommen.

Wenn Sie die Sache zu möchten, können Sie Wachen verwenden:

{x:t ⋄ f} 

Dies entspricht zu

if (x) { 
    return t; 
} 
f; 

in einer C-ähnlichen Sprache.

+3

Schön. Das ist Dyalog-spezifisch, oder? – Tobia

+2

Ja. Welche APL-Implementierung verwenden Sie? – ngn

+0

er dumme Frage. ist ein Liner erforderlich? (Ja, ich weiß, das ist APL), aber wenn Sie vermeiden möchten, beide Funktionen auszuführen, was mit einer einfachen bedingten Ausführung falsch ist. (Tut mir leid, ich habe keine APL-Tastatur), etwas wie: ... execute (some_boolean)/'f' ausführen (~ some_boolean)/'t' Klarheit ist keine Sünde! – RFlack

2

Eine alte, alte Sprache, die etwas tat wie der C ternäre Operator ? : und ergab ein Ergebnis war die folgende:

r←⍎(¯3 3)[x=42]↑'6×8 ⋄ 6×7' 

Beachten Sie, dass diese 0 für Herkunft geschrieben und die Pars um die -3 3 gibt es zur Klarheit.

x = 42 werten auf Null oder Eins, zu dieser Antwort in Abhängigkeit wir wählen -3 oder 3 und damit auswählen und ausführen, entweder die ersten 3-Elemente („6x8“), oder die letzten 3 Elemente („6x7“) der Zeichenfolge. Der Diamant ⋄ ist nur zur Dekoration da.

Unnötig zu sagen, würde man diesen Weg wahrscheinlich nicht codieren, wenn man hätte: if: else available, obwohl die Kontrollstrukturform kein Ergebnis zurückgeben würde.

+0

Ist das nicht ein bisschen unordentlich? (Ich hasse es, Längen von Char-Vektoren zu zählen!). Ich habe keine APL-Tastatur hier aber könnte man nicht ein verschachteltes Array von zwei Char-Vektoren als das Rarg der nehmen? Ich vermute, die Antwort auf das OP hängt von dem Kontext ab, der mir nicht völlig klar war. – RFlack

+0

Das letzte Mal sah oder benutzte ich das um 1979 auf dem einen oder anderen (Sharp oder STSC) Timesharing-System. Verschachtelte Arrays waren zu der Zeit nicht verfügbar. – Lobachevsky

2

In Dyalog APL können Sie:

'value if true' (⊣⍣condition) 'value if false' 

Die Idee bewirbt (links tack - die immer seine linke Argument zurückgibt, während das rechte Argument verwerfen) entweder 0 (für falsch) oder 1 (für true) mal - zum richtigen Argument. Wenn es 0 Mal angewendet wird (d. H. Überhaupt nicht), wird das rechte Argument unverändert zurückgegeben, aber wenn es einmal angewendet wird, wird das linke Argument angewendet. ZB:

 a b←3 5 
     Conditional←⊣⍣(a=b) 
     'match' Conditional 'different' 
different 
     a b←4 4 
     Conditional←⊣⍣(a=b) 
     'match' Conditional 'different' 
match 

oder

 Cond←{⍺(⊣⍣⍺⍺)⍵} 
     bool←a=b 
     'match'(bool Cond)'different' 
match 
+0

Sollte das zweite Ergebnis nicht übereinstimmen? – Uriel

+0

@Uriel Ja, danke. –

0

Dies ist eine häufig gestellte Frage ist, ich glaube, der Grund, warum es es keine Standard-Antwort ist, dass für die Dinge, die Sie mit APL tun, gibt es tatsächlich weniger Bedarf an es als andere Sprachen.

Das heißt, ist es manchmal nötig, und die Art, wie ich einen IFELSE Operator in GNU APL implementieren wird mit dieser Funktion:

 3 {'expression is true' ⍵} IFELSE {'was false' ⍵} 0 
was false 3 

:

∇Z ← arg (truefn IFELSE falsefn) condition ;v 
    v←⍬ 
    →(0=⎕NC 'arg')/noarg 
    v←arg 
noarg: 
    →condition/istrue 
    Z←falsefn v 
    →end 
istrue: 
    Z←truefn v 
end: 
∇ 

Die Funktion kann wie folgt aufgerufen werden Diese spezielle Implementierung übergibt das linke Argument als an die Klausel, weil das manchmal nützlich sein kann. Ohne ein linkes Argument geht es in über.

0

Der APL-Ausdruck:

(1+x=0)⌷y z 

die Sprache C-Äquivalent für

x?y:z 

Und all die anderen

(1+x>0)⌷y z 

für

x<=0?y:z 
sein sollte

Etc. Im Allgemeinen, wenn a b c ist Ausdruck der jeweiligen Sprachen des APL-Ausdruck:

(1+~a)⌷b c 

Es sollte auf die C-Sprache entsprechen:

a?b:c