Pourquoi des expressions composées?


10

Voici un exemple d'un livre que je lis:

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

Pourquoi ai-je besoin d'expressions composées ?? Je pourrais simplement écrire volume = 10 * 20 * 30ou volume = len * breadth * heightou écrire une fonction pour cela ou une fonction anonyme ...

Pourquoi dois-je utiliser beginet end? Ou la question probablement meilleure: quand dois-je les utiliser, car je suppose que l'exemple ci-dessus du livre n'est probablement pas très bon.


1
Quel livre est-ce? comme vous aussi, l'exemple n'est pas particulièrement bon
Michael K. Borregaard

"Learning Julia", disponible ici: epdf.pub/learning-julia.html (page 127)
Georgery

Réponses:


4

Je suppose qu'il existe de nombreuses situations dans lesquelles les begin ... endblocs sont pratiques, mais comme vous l'avez noté, vous pouvez souvent également obtenir un effet similaire avec d'autres constructions, telles que des fonctions, etc.

À quoi pourraient begin ... endservir les blocs?

  • Pour simplement « contenir » les variables et leur nom: len, breadthet heightexistera uniquement dans le bloc et ne pollue pas l'espace de noms environnant.
  • Appliquer des macros à un bloc de code plutôt qu'à des instructions individuelles. Par exemple, @inbounds begin <all my code without bounds checking goes here> endou enrouler un @time begin ... endautour d'un morceau de code.
  • Pour créer une portée locale dans une portée globale environnante (pour éviter les confusions de portée globale par exemple). (Notez que comme cela a été souligné dans les commentaires begin ... endn'introduit pas de portée locale, mais l'argument est valable pour le let ... endbloc similaire .)

En particulier, le deuxième point est la raison pour laquelle je les utilise dans mes codes.


Je devais aussi me rassurer, mais les beginblocs ne pas présenter la portée . D'un autre côté, ils convertissent une séquence d'instructions en une expression, ce qui peut être pratique si vous générez du code avec / à partir d'une macro.
phipsgabler

1
Oh, merci, à cet égard, je l'ai confondu avec let ... endce qui introduit une portée locale. Corrigera ma réponse.
crstnbr

Je fais toujours la même hypothèse erronée :) C'est exactement ce à quoi on pourrait s'attendre.
phipsgabler

1
@crstnbr Votre première puce est toujours trompeuse. Il semble toujours que les beginblocs introduisent une portée locale.
Cameron Bieganek

7

Pour généraliser ce que tout le monde a dit: les blocs vous permettent de convertir une liste d' instructions ("phrases" syntaxiques qui n'ont pas de valeurs, c'est-à-dire ne peuvent pas être affectées) en une expression (une "phrase" qui représente des valeurs et peut être affectée ).

Par exemple, alors que vous ne devriez pas, vous pouvez écrire

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

à affecter xau résultat d'une opération de bouclage. (Avec la restriction que la dernière instruction de la séquence doit en fait être une expression - sinon, vous n'auriez aucune valeur pour l'expression.)

Un cas d'utilisation légitime de ce code est généré. Par exemple, vous pouvez activer

x = @somthing bla blub

dans

x = begin
   (stuff involving bla and blub)
end

de manière transparente pour l'utilisateur, tandis que le @somethingpeut générer librement toutes les constructions de langage.

Ou si vous voulez écrire une fonction anonyme avec un corps plus long (et ne pas utiliser le functionformulaire):

f = x -> begin
   ...
end

1
Une petite clarification: dans Julia, les déclarations ont des valeurs et peuvent être affectées. Ainsi , vous pouvez le faire x = y = 1, a = if false endet b = for i in 1:2 end, après quoi xa la valeur 1, et aet les bdeux ont la valeur nothing.
Cameron Bieganek

Oh, voici un exemple plus utile d'affecter la valeur d'une if-elsedéclaration: a = if false; 1 else 2 end. Dans ce cas, aest égal à 2.
Cameron Bieganek

1
C'est vrai, ils ont des valeurs et sont aussi des expressions techniques. L'affectation est une expression, car c'est fondamentalement setproperty!/ setindex!, et c'est "traditionnellement" une chose pour qu'elle ait une valeur (dans les langages de type C). Pareil pour if-else, qui est une expression dans deux langues. Mais foret ifsans elseavoir une valeur "par défaut" de nothing, je vois cela comme un simple artefact.
phipsgabler

6

Une utilisation pour ces blocs est dans les compréhensions:

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

Vous pouvez créer une fonction et l'utiliser à la place dans la compréhension, mais cela est parfois pratique. Il est utilisé chaque fois que vous souhaitez utiliser un bloc de code multiligne quelque part, par exemple pour passer comme argument à une macro (qui est très couramment utilisée @testsetdans la bibliothèque standard de test).


Pour ne pas s'opposer à votre point mais on pourrait simplement écrire y^2 - y^4 + 2dans ce cas. Il serait peut-être préférable de montrer un exemple où deux (ou plus) étapes sont vraiment nécessaires.
crstnbr

@crstnbr vous avez raison, mais j'ai tout d'abord utilisé l'exemple du livre et j'étais simplement intéressé par ce que serait une utilisation sensée.
Georgery

1
Par exemple, pour économiser deux fois le calcul d'une valeur intermédiaire coûteuse.
phipsgabler

5

Autrement dit: «commencer» désigne simplement un bloc de code (voir la documentation à ce sujet: https://docs.julialang.org/en/v1/base/base/#begin ).

Dans l'exemple ci-dessus, il n'est pas clair qu'il y ait une quelconque valeur à utiliser un bloc begin vs déclarer une fonction.

Je ne vois pas ce mot-clé très utilisé dans le code et personnellement je ne l'ai jamais utilisé dans la pratique. Ma suggestion donc d'utiliser simplement une fonction car elle fera la même chose.


Je n'ai pas encore utilisé Julia, mais c'est exactement ce que je pense. Cependant, lorsque le langage a été conçu (probablement très intelligent), les gens devaient avoir une idée en tête, non?
Georgery

Je suis d'accord avec @logankilpatrick que dans de nombreux cas, vous voudriez utiliser des fonctions à la place. Mais je pense qu'il y a des raisons à l'existence de ces blocs (voir ma réponse).
crstnbr

@Georgery Transformer une séquence d'instructions en une expression est parfois une chose utile (cf. progndans LISP).
phipsgabler

1
comme vous le constatez correctement, cela semble absurde dans le contexte
Michael K. Borregaard
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.