なぜ複合式ですか?


10

これは私が読んでいる本の例です:

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

なぜ複合式が必要なのですか?私はそのための関数または匿名関数を書くvolume = 10 * 20 * 30か、volume = len * breadth * heightまたは書くことができます...

なぜ私は使用beginendますか?またはおそらくより良い質問: 私がそれらをいつ使用するか、本の上の例はおそらくあまり良くないようです。


1
それは何の本ですか?あなたもそうではないので、この例は特に良くありません
マイケルK.ボレガード

「Learning Julia」、ここで入手可能:epdf.pub/learning-julia.html(127ページ)
Georgery

回答:


4

私は多くの状況があると思います begin ... endブロックが便利なますが、お気づきのように、関数などの他の構成要素でも同様の効果を達成できることがよくあります。

どのような可能性 begin ... endブロックはに使用ますか?

  • 単に変数と自分の名前を「含んで」するにはlenbreadth、およびheightブロック内に存在するのみで、周囲の名前空間を汚染しないであろう。
  • 個々のステートメントではなくコードのブロックにマクロを適用する。例えば@inbounds begin <all my code without bounds checking goes here> endまたは@time begin ... endコードの一部をラップします。
  • 周囲のグローバルスコープにローカルスコープを作成する(たとえば、グローバルスコープの混乱を避けるため)。(コメントで指摘されているように、ローカルスコープ導入されてbegin ... endいませが、同様のlet ... endブロックにます。)

特に2番目のポイントは、コードでそれらを使用する目的です。


私も安心しなければなりませんでしたが、beginブロックはスコープを導入しません。一方、一連のステートメントは式に変換されます。これは、マクロを使用して、またはマクロからコードを生成する場合に便利です。
phipsgabler

1
ああ、ありがとう。その点でlet ... end、ローカルスコープを導入するのと混同してしまいました。私の答えを修正します。
crstnbr

私はいつも同じ間違った仮定をします:)それは人が期待するものです。
フィップスガブラー

1
@crstnbr最初の弾丸はまだ誤解を招くものです。それでもbeginブロックはローカルスコープを導入すると言っているようです。
Cameron Bieganek

7

他の誰もが言ったことを一般化するには:ブロックを使用すると、ステートメントのリスト(値を持たない、つまり割り当てることができない構文の「フレーズ」)を1つの(値を表し、割り当てることできる「フレーズ」)に変換できます。 )。

たとえば、すべきではありませんが、次のように書くことができます

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

xループ操作の結果に割り当てます。(シーケンスの最後のステートメントは実際には式でなければならないという制限があるため、そうでなければ、式の値はありません。)

これの正当なユースケースは生成されたコードです。たとえば、

x = @somthing bla blub

x = begin
   (stuff involving bla and blub)
end

はユーザーに対して透過的ですが、@somethingは任意の言語構造を自由に生成できます。

または、より長い本体を持つ無名関数を記述したい場合(functionフォームを使用しない場合):

f = x -> begin
   ...
end

1
若干の明確化:ジュリアでは、ステートメントには値あり、割り当てることできます。あなたが行うことができますのでx = y = 1a = if false end、そしてb = for i in 1:2 end、その後にx値を持っている1、とabの両方が値を持っていますnothing
Cameron Bieganek

ああ、これはif-elseステートメントの値を割り当てるより便利な例ですa = if false; 1 else 2 end。この場合、aはに等しくなり2ます。
Cameron Bieganek

1
そうです、それらには価値があり、技術的にも表現です。代入は式です。基本的にはsetproperty!/ setindex!であり、(伝統的に)値を持つこと(Cのような言語では)です。も同じですif-else。これは、いくつかの言語での表現です。しかし、forおよびifなしelseの「デフォルト」の値を持つnothing、私は単にアーティファクトとしてそれを参照してください。
phipsgabler

6

これらのブロックの用途の1つは理解にあります。

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

関数を作成し、代わりに内包の中で使用することもできますが、これは便利な場合があります。マクロに引数として渡すなど、コードの複数行のブロックをどこかで使用したい場合に常に使用されます(これは@testset、テストの標準ライブラリから非常によく使用されます)。


あなたの主張に反対するわけではありませんがy^2 - y^4 + 2、この場合はただ書くことができます。おそらく、2つ(またはそれ以上)のステップが本当に必要な例を示す方が良いでしょう。
crstnbr

@crstnbrあなたは正しいですが、私は最初に本の例を使用しただけで、単に賢明な使用法が何であるかに興味を持っていました。
ジョージリー

1
同様に、高価な中間値を2回計算することを節約します。
phipsgabler

5

簡単に言えば、「begin」は単にコードブロックを示します(これに関するドキュメントを参照してくださいhttps : //docs.julialang.org/en/v1/base/base/#begin)。

上記の例では、begin blockを使用することと関数を宣言することに何らかの価値があることは明らかではありません。

そのキーワードがコードであまり使われていないように見えますし、個人的には実際には使用していません。同じことをするので、関数を使用するだけの私の提案。


私はまだジュリアを使用していませんが、これはまさに私が考えていることです。しかし、言語が設計されたとき(おそらく非常にスマート)、人々は考えを持っているに違いありませんよね?
ジョージリー

@logankilpatrickに同意します。多くの場合、代わりに関数を使用します。しかし、これらのブロックが存在する理由はあると思います(私の回答を参照)。
crstnbr

@Georgeryステートメントのシーケンスを式に変換することが役立つ場合があります(prognLISPを参照)。
phipsgabler

1
あなたが正しく注意しているように、それは文脈では無意味だと思われます
Michael K. Borregaard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.