Warum zusammengesetzte Ausdrücke?

10

Dies ist ein Beispiel aus einem Buch, das ich lese:

volume = begin
    len = 10
    breadth = 20
    height = 30
    len * breadth * height
end

Warum brauche ich zusammengesetzte Ausdrücke? Ich könnte einfach eine Funktion für diese oder eine anonyme Funktion schreiben volume = 10 * 20 * 30oder volume = len * breadth * heightschreiben ...

Warum benutze ich beginund end? Oder die wahrscheinlich bessere Frage: Wann verwende ich sie, da das obige Beispiel aus dem Buch wahrscheinlich nicht sehr gut ist.

Georgery
quelle
1
Welches Buch ist das? da du auch nicht das beispiel nicht besonders gut bist
Michael K. Borregaard
"Learning Julia", wie hier verfügbar: epdf.pub/learning-julia.html (Seite 127)
Georgery

Antworten:

4

Ich denke, es gibt viele Situationen, in denen begin ... endBlöcke praktisch sind, aber wie Sie bemerkt haben, können Sie oft auch mit anderen Konstrukten wie Funktionen usw. einen ähnlichen Effekt erzielen.

Wofür könnten begin ... endBlöcke verwendet werden?

  • Um einfach „enthalten“ Variablen und ihre Namen: len, breadth, und heightbesteht nur innerhalb des Blocks und nicht die umgebenden Namensraum verschmutzen.
  • Anwenden von Makros auf einen Codeblock anstatt auf einzelne Anweisungen. Zum Beispiel @inbounds begin <all my code without bounds checking goes here> endoder @time begin ... endum einen Code herum.
  • So erstellen Sie einen lokalen Bereich in einem umgebenden globalen Bereich (um beispielsweise Verwirrungen im globalen Bereich zu vermeiden ). (Beachten Sie, dass, wie in den Kommentaren begin ... enderwähnt, kein lokaler Bereich eingeführt wird, das Argument jedoch für den ähnlichen let ... endBlock gilt.)

Insbesondere ist der zweite Punkt, wofür ich sie in meinen Codes verwende.

crstnbr
quelle
Ich musste mich auch beruhigen, aber beginBlöcke führen keinen Umfang ein . Andererseits konvertieren sie eine Folge von Anweisungen in einen Ausdruck, was nützlich sein kann, wenn Sie Code mit / aus einem Makro generieren.
Phipsgabler
1
Oh, danke, in dieser Hinsicht habe ich es verwechselt, let ... endwas einen lokalen Bereich einführt. Wird meine Antwort korrigieren.
7.
Ich mache die ganze Zeit die gleiche falsche Annahme :) Es ist genau das, was man erwarten würde.
Phipsgabler
1
@crstnbr Deine erste Kugel ist immer noch irreführend. Es scheint immer noch zu sagen, dass beginBlöcke einen lokalen Bereich einführen.
Cameron Bieganek
7

Zu verallgemeinern , was alle anderen gesagt hat: Blöcke können Sie eine Liste von konvertieren Aussagen (syntaktische „Sätze“ , die keine Werte haben, dh sie können nicht zugeordnet werden) zu einem Ausdruck (eine „Phrase“ , die Werte darstellt , und können zugeordnet werden ).

Während Sie zum Beispiel nicht sollten, können Sie schreiben

x = begin
    s = 0
    for i = 1:10
        s += i^2
    end
    s
end

xdem Ergebnis einer Schleifenoperation zuzuweisen . (Mit der Einschränkung, dass die letzte Anweisung in der Sequenz tatsächlich ein Ausdruck sein muss - andernfalls hätten Sie keinen Wert für den Ausdruck.)

Ein legitimer Anwendungsfall hierfür ist generierter Code. Zum Beispiel könnten Sie sich umdrehen

x = @somthing bla blub

in

x = begin
   (stuff involving bla and blub)
end

transparent für den Benutzer, während der @somethingfrei beliebige Sprachkonstrukte erzeugen kann.

Oder wenn Sie eine anonyme Funktion mit einem längeren Text schreiben möchten (und das functionFormular nicht verwenden möchten ):

f = x -> begin
   ...
end
phipsgabler
quelle
1
Eine kleine Klarstellung: In Julia haben Aussagen Werte und können zugeordnet werden. Sie können also tun x = y = 1, a = if false endund b = for i in 1:2 enddanach xhat der Wert 1, aund bbeide haben den Wert nothing.
Cameron Bieganek
Oh, hier ist ein nützlicheres Beispiel für die Zuweisung des Werts einer if-elseAnweisung : a = if false; 1 else 2 end. In diesem Fall ist agleich 2.
Cameron Bieganek
1
Richtig, sie haben Werte und sind auch technische Ausdrücke. Zuweisung ist ein Ausdruck, da es im Grunde genommen setproperty!/ setindex!ist und es "traditionell" eine Sache ist, einen Wert zu haben (in C-ähnlichen Sprachen). Gleiches gilt für if-elseeinen Ausdruck in mehreren Sprachen. Aber forund ifohne elseeinen "Standard" -Wert von zu haben nothing, sehe ich das nur als Artefakt.
Phipsgabler
6

Eine Verwendung für diese Blöcke liegt im Verständnis:

A = [ begin
           x = y^2
           x - x^2 + 2
         end
         for y = 1:5 ]

Sie könnten eine Funktion erstellen und stattdessen innerhalb des Verständnisses verwenden, aber manchmal ist dies praktisch. Es wird immer dann verwendet, wenn Sie irgendwo einen mehrzeiligen Codeblock verwenden möchten, z. B. um ihn als Argument an ein Makro zu übergeben (das in der Teststandardbibliothek sehr häufig verwendet wird @testset).

Eric
quelle
Um sich Ihrem Standpunkt nicht zu widersetzen, könnte man y^2 - y^4 + 2in diesem Fall einfach schreiben . Vielleicht wäre es besser, ein Beispiel zu zeigen, in dem zwei (oder mehr) Schritte wirklich benötigt werden.
7.
@crstnbr Sie haben Recht, aber ich habe gerade das Beispiel aus dem Buch verwendet und war einfach interessiert, was eine vernünftige Verwendung wäre.
Georgery
1
Zum Beispiel, um die Berechnung eines teuren Zwischenwerts zweimal zu sparen.
Phipsgabler
5

Einfach ausgedrückt: "begin" bezeichnet nur einen Codeblock (siehe die Dokumentation dazu: https://docs.julialang.org/en/v1/base/base/#begin ).

Im obigen Beispiel ist nicht klar, ob die Verwendung eines begin-Blocks oder die Deklaration einer Funktion einen Wert hat.

Ich sehe nicht, dass dieses Schlüsselwort im Code sehr häufig verwendet wird, und ich persönlich habe es in der Praxis nie verwendet. Mein Vorschlag, einfach eine Funktion zu verwenden, da sie das Gleiche tut.

logankilpatrick
quelle
Ich habe Julia noch nicht benutzt, aber genau das denke ich. Als die Sprache entworfen wurde (vermutlich sehr klug), müssen die Leute eine Idee gehabt haben, oder?
Georgery
Ich stimme @logankilpatrick zu, dass Sie in vielen Fällen stattdessen Funktionen verwenden möchten. Aber ich denke, es gibt Gründe für die Existenz dieser Blöcke (siehe meine Antwort).
7.
@Georgery Manchmal ist es nützlich, eine Folge von Anweisungen in einen Ausdruck umzuwandeln (vgl. prognIn LISP).
Phipsgabler
1
Wie Sie richtig bemerken, erscheint es im Kontext unsinnig
Michael K. Borregaard