开发者

When do you put double semicolons in F#?

This is a stupid questio开发者_Go百科n. I've been reading a couple books on F# and can't find anything that explains when you put ;; after a statement, nor can I find a pattern in the reading. When do you end a statement with double semi-colons?


In the non-interactive F# code that's not supposed to be compatible with OCaml, you shouldn't need to ever need double semicolon. In the OCaml compatible mode, you would use it at the end of a top-level function declaration (In the recent versions, you can switch to this mode by using files with .ml extension or by adding #light "off" to the top).

If you're using the command-line fsi.exe tool or F# Interactive in Visual Studio then you'd use ;; to end the current input for F#.

When I'm posting code samples here at StackOverflow (and in the code samples from my book), I use ;; in the listing when I also want to show the result of evaluating the expression in F# interactive:

  • Listing from F# interactive

    > "Hello" + " world!";;
    val it : string = "Hello world!"
    > 1 + 2;;
    val it : int = 3
    
  • Standard F# source code

    let n = 1 + 2
    printf "Hello world!"
    

Sometimes it is also useful to show the output as part of the listing, so I find this notation quite useful, but I never explained it anywhere, so it's great that you asked!


Are you talking about F# proper or about running F# functions in the F# Interactive? In F# Interactive ;; forces execution of the code just entered. other than that ;; does not have any special meaning that I know of


In F#, the only place ;; is required is to end expressions in the interactive mode.

;; is left over from the transition from OCaml, where in turn it is left over from Caml Light. Originally ;; was used to end top-level "phrases"--that is, let, type, etc. OCaml made ;; optional since the typical module consists of a series of let statements with maybe one statement at the end to call the main function. If you deviate from this pattern, you need to separate the statements with ;;. Unfortunately, in OCaml, when ;; is optional versus required is hard to learn.

However, F# introduces two relevant modifications to OCaml syntax: indentation and do. Top-level statements have to go inside a do block, and indentation is required for blocks, so F# always knows that each top-level statement begin with do and an indent and ends with an outdent. No more ;; required.

Overall, all you need to know is that [O']Caml's syntax sucks, and F# fixes a lot of its problems, but maintains a lot of confusing backward compatibility. (I believe that F# can still compile a lot of OCaml code.)

Note: This answer was based on my experience with OCaml and the link Adam Gent posted (which is unfortunately not very enlightening unless you know OCaml).


Symbol and Operator Reference (F#)

http://msdn.microsoft.com/en-us/library/dd233228(v=VS.100).aspx

Semi Colon:

•Separates expressions (used mostly in verbose syntax).

•Separates elements of a list.

•Separates fields of a record.

Double Semi Colon:

http://www.ffconsultancy.com/products/fsharp_journal/free/introduction.html

Articles in The F#.NET Journal quote F# code as it would appear in an interactive session. Specifically, the interactive session provides a > prompt, requires a double semicolon ;; identifier at the end of a code snippet to force evaluation, and returns the names (if any) and types of resulting definitions and values.


I suspect that you have seen F# code written when #light syntax wasn't enabled by default (#light syntax is on by default for the May 2009 CTP and later ones as well as for Visual Studio 2010) and then ;; means the end of a function declaration.

So what is #light syntax? It comes with the #light declaration:

The #light declaration makes whitespace significant. Allowing the developer to omit certain keywords such as in, ;, ;;, begin, and end.

Here's a code written without #light syntax:

let halfWay a b =
  let dif =  b - a in
  let mid = dif / 2 in
  mid + a;;

and becomes with light syntax:

#light
let halfWay a b =
  let dif =  b - a
  let mid = dif / 2
  mid + a

As said you can omit the #light declaration now (which should be the case if you're on a recent CTP or Visual Studio 2010).

See also this thread if you want know more on the #light syntax: F# - Should I learn with or without #light?


The double semi-colon is used to mark the end of a block of code that is ready for evaluation in F# interactive when you are typing directly into the interactive session. For example, when using it as a calculator.

This is rarely seen in F# because you typically write code into a script file, highlight it and use ALT+ENTER to have it evaluated, with Visual Studio effectively injecting the ;; at the end for you.

OCaml is the same.

Literature often quotes code written as it would appear if it had been typed into an interactive session because this is a clear way to convey not only the code but also its inferred type. For example:

> [1; 2; 3];;
val it : int list = [1; 2; 3]

This means that you type the expression [1; 2; 3] into the interactive session followed by the ;; denoting the end of a block of code that is ready to be evaluated interactively and the compiler replies with val it : int list = [1; 2; 3] describing that the expression evaluated to a value of the type int list.


The double semicolon most likely comes from OCaml since that is what the language is based on. See link text

Basically its for historical purposes and you need it for the evaluator (repl) if you use it.


There is no purpose for double semi-colons (outside of F# interactive). The semi-colon, according to MSDN:

  • Separates expressions (used mostly in verbose syntax).
  • Separates elements of a list.
  • Separates fields of a record.

Therefore, in the first instance, ;; would be separating the expression before the first semi-colon from the empty expression after it but before the second semi-colon, and separating that empty expression from whatever came after the second semi-colon (just as in, say C# or C++).

In the instance of the list, I suspect you'd get an error for defining an empty list element.

With regards to the record, I suspect it would be similar to separating expressions, with the empty space between the semi-colons effectively being ignored.

F# interactive executes the entered F# on seeing a double semi-colon.

[Updated to cover F# interactive - courtesy of mfeingold)


The history of the double semicolon can be traced back to the beginnings of ML when semicolons were used as a separator in lists instead of commas. In this ICFP 2010 - Tribute to Robin Milner video around 50:15 Mike Gordon mentions:

There was a talk on F# where someone asked "Why is there double semicolon on the end of F# commands?" The reason is the separator in lists in the original ML is semicolons, so if you wanted a list 1;2;3; and put it on separate lines- if you ended a line with semicolon you were not ending the phrase, so using double semicolon meant the end of the expression. Then in Standard ML the separator for lists became comma, so that meant you could use single semicolons to end lists.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜