

.mlファイルの中のOCamlコードで、以下のようなコードを書いた際、

[code]

    let print_for_print_test str =
      for i = 0 to String.length-1 str do
        print_string(str)
        print_newline()
      done;;
    
[/code]

3行目に `;` が足りない、という意味のエラーメッセージが出ました。実際に `;` を補えばうまくいったのですが、OCamlでの `;` と `;;`
の違いがよく分かりません。よろしければご教授お願いします。


CC BY-SA 4.0
2014-12-02T13:50:47.863
263
2021-03-10T14:59:42.623
2021-03-10T14:59:42.623
3060
667
question
ocaml
OCamlの ; と ;; の違いが分からない


[こちら(ocaml.org)](https://ocaml.org/learn/tutorials/structure_of_ocaml_programs.ja.html#_4)
が参考になると思います。

一部を抜粋します。

> ルール1。;;を使うべきときとは、コードのトップレベルにある文を区切るときだ。関数定義の中のときや、他の文のときは、いらない。
>
> ルール3と4は、一重の;についてだ。こいつは、;;とは完全に別物だ。セミコロンひとつの;は、
> シークエンスポイントということになっている。言ってみれば、これは、C、C++、Java、Perlのセミコロンひとつと全く同じことである。

* * *

3行目のみ必要な点については、 4行目はブロックの最後なので `;`が無くても式の終わりがわかりますが、 3行目はそうではないので 式の区切りを示す `;`
が必要となります。


CC BY-SA 3.0
2014-12-02T17:56:44.847
271
2014-12-03T13:02:11.443
2014-12-03T13:02:11.443
728
728
263
answer


仕様を見てみましょう。

<http://caml.inria.fr/pub/docs/manual-ocaml-400/language.html>

<http://caml.inria.fr/pub/docs/manual-ocaml-400/manual020.html>

Compilation unitsとspecification,definitionを抜粋すると以下のように定義されています。

[code]

    unit-interface ::=  { specification  [;;] } 
    unit-implementation ::=  { definition  [;;] }    
    
    specification   ::= val value-name :  typexpr  
        ∣    external value-name :  typexpr =  external-declaration  
        ∣    type-definition  
        ∣    exception constr-decl  
        ∣    class-specification  
        ∣    classtype-definition  
        ∣    module module-name :  module-type  
        ∣    module module-name  { ( module-name :  module-type ) } :  module-type  
        ∣    module type modtype-name  
        ∣    module type modtype-name =  module-type  
        ∣    open module-path  
        ∣    include module-type  
    
    definition  ::= let [rec] let-binding   { and let-binding }  
        ∣    external value-name :  typexpr =  external-declaration  
        ∣    type-definition  
        ∣    exception-definition  
        ∣    class-definition  
        ∣    classtype-definition  
        ∣    module module-name  { ( module-name :  module-type ) }  [ : module-type ]  =  module-expr  
        ∣    module type modtype-name =  module-type  
        ∣    open module-path  
        ∣    include module-expr
    
[/code]

OCamlには定義と仕様(まとめて文と呼ぶ)と式の３つがあり、文の区切りには;;を使い、;は式を連続して記述する事に使うと覚えると良さそうです。;;は省略可能ですが、トップレベルや必要なときに使います。

let a = 1は定義で、  
val a:intが仕様で、  
let b = 1 in bは式です。

[code]

    let a = ();();();1;;
    
[/code]

はaに1を定義しています。  
文として式を書く事も出来るのでトップレベルに式を並べて

[code]

    1;;
    2;;
    let b = 1 in b;;
    3
    
[/code]

のように書く事も出来ます。  
式を文として連続して書くような場合は;;を書く必要があります。

[code]

    f
    1
    
[/code]

と書くとOCamlでは改行は意味を持たないのでf関数に引数1を適用する意味になります。


CC BY-SA 3.0
2015-01-19T11:54:47.257
4847
2015-01-19T11:54:47.257
7532
263
answer