Perché espressioni composte?


10

Questo è un esempio di un libro che sto leggendo:

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

Perché ho bisogno di espressioni composte ?? Potrei semplicemente scrivere volume = 10 * 20 * 30o volume = len * breadth * heighto scrivere una funzione per quella o una funzione anonima ...

Perché uso begine end? O la domanda probabilmente migliore: quando li uso, come immagino che l'esempio sopra del libro non sia probabilmente molto buono.


1
Che libro è quello? poiché anche tu non l'esempio non è particolarmente buono
Michael K. Borregaard il

"Learning Julia", disponibile qui: epdf.pub/learning-julia.html (pagina 127)
Georgery

Risposte:


4

Immagino che ci siano molte situazioni in cui i begin ... endblocchi sono utili, ma come hai notato spesso puoi anche ottenere un effetto simile con altri costrutti, come funzioni, ecc.

A cosa potrebbero begin ... endservire i blocchi?

  • Per semplicemente "contenere" variabili ed i loro nomi: len, breadth, e heightesisterà solo all'interno del blocco e non inquinare il namespace circostante.
  • Per applicare le macro a un blocco di codice anziché a singole istruzioni. Ad esempio @inbounds begin <all my code without bounds checking goes here> endo racchiudendo un @time begin ... endintorno a un pezzo di codice.
  • Per creare un ambito locale in un ambito globale circostante (per evitare, ad esempio, confusioni di ambito globale ). (Si noti che, come è stato sottolineato nei commenti begin ... endnon senza introdurre un ambito locale, ma il discorso vale per il simile let ... endblocco.)

In particolare il secondo punto è quello per cui li uso nei miei codici.


Ho anche dovuto rassicurarmi, ma beginblocca non senza introdurre portata . D'altra parte, convertono una sequenza di istruzioni in un'espressione, che può essere utile se si genera codice con / da una macro.
phipsgabler

1
Oh, grazie, a tale proposito, l'ho confuso con il let ... endquale introduce un ambito locale. Correggerò la mia risposta.
crstnbr

Faccio sempre lo stesso presupposto sbagliato :) È proprio quello che ci si aspetterebbe.
phipsgabler

1
@crstnbr Il tuo primo proiettile è ancora fuorviante. Sembra ancora che i beginblocchi introducano un ambito locale.
Cameron Bieganek il

7

Per generalizzare ciò che tutti gli altri hanno detto: i blocchi consentono di convertire un elenco di istruzioni ("frasi" sintattiche che non hanno valori, cioè che non possono essere assegnati) in un'espressione (una "frase" che rappresenta valori e può essere assegnata ).

Ad esempio, mentre non dovresti, puoi scrivere

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

per assegnare xal risultato di un'operazione di loop. (Con la restrizione che l'ultima istruzione della sequenza deve effettivamente essere un'espressione, altrimenti non avresti alcun valore per l'espressione.)

Un caso d'uso legittimo di questo è il codice generato. Ad esempio, potresti girare

x = @somthing bla blub

in

x = begin
   (stuff involving bla and blub)
end

in modo trasparente per l'utente, mentre @somethingpuò generare liberamente qualsiasi costrutto di linguaggio.

O se vuoi scrivere una funzione anonima con un corpo più lungo (e non usare il functionmodulo):

f = x -> begin
   ...
end

1
Un lieve precisazione: in Julia, le dichiarazioni non hanno valori e può essere assegnato. Così si può fare x = y = 1, a = if false ende b = for i in 1:2 end, dopo di che xha il valore 1, ed ae bentrambi hanno il valore nothing.
Cameron Bieganek il

Oh, ecco un esempio più utile di assegnare il valore di una if-elsedichiarazione: a = if false; 1 else 2 end. In questo caso, è auguale 2.
Cameron Bieganek il

1
Esatto, hanno valori e sono anche espressioni tecnologiche. L'assegnazione è un'espressione, dal momento che è sostanzialmente setproperty!/ setindex!, ed è "tradizionalmente" una cosa per avere un valore (in linguaggi simili a C). Lo stesso per if-else, che è un'espressione in un paio di lingue. Ma fore ifsenza elseavere un valore "predefinito" di nothing, lo vedo come un semplice artefatto.
phipsgabler

6

Un uso di questi blocchi è nelle comprensioni:

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

Potresti invece creare una funzione e usarla all'interno della comprensione, ma a volte è conveniente. Viene utilizzato ogni volta che si desidera utilizzare un blocco di codice multilinea da qualche parte, ad esempio per passare come argomento a una macro (che è molto comunemente usata per @testsetla libreria standard Test).


Non per opporti al tuo punto, ma si potrebbe semplicemente scrivere y^2 - y^4 + 2in questo caso. Forse sarebbe meglio mostrare un esempio in cui sono necessari due (o più) passaggi.
crstnbr

@crstnbr hai ragione, ma inizialmente ho usato l'esempio del libro ed ero semplicemente interessato a quale sarebbe stato un uso ragionevole.
Georgery

1
Ad esempio, per risparmiare calcolando due volte un valore intermedio costoso.
phipsgabler

5

In poche parole: "begin" indica solo un blocco di codice (vedere i documenti su questo: https://docs.julialang.org/en/v1/base/base/#begin ).

Nell'esempio sopra, non è chiaro che esiste un valore nell'uso di un blocco di inizio rispetto alla dichiarazione di una funzione.

Non vedo quella parola chiave usata molto nel codice e personalmente non l'ho mai usata in pratica. Il mio consiglio è quindi di usare solo una funzione perché farà la stessa cosa.


Non ho ancora usato Julia, ma questo è esattamente quello che sto pensando. Tuttavia, quando il linguaggio è stato progettato (presumibilmente molto intelligente) le persone devono aver avuto un'idea in mente, giusto?
Georgery

Concordo con @logankilpatrick sul fatto che in molti casi vorresti utilizzare le funzioni. Ma penso che ci siano ragioni per l'esistenza di questi blocchi (vedi la mia risposta).
crstnbr

@Georgery Trasformare una sequenza di istruzioni in un'espressione è talvolta utile (cfr. prognIn LISP).
phipsgabler

1
come noterai correttamente, sembra assurdo nel contesto
Michael K. Borregaard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.