tags:

views:

270

answers:

2

I just started learning F#, and tried a code from the wiki:

I prefer tabs to spaces, so I change the code a bit into this:

#indent "off"
open System
open System.Windows.Forms

let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")

let label =
    let temp = new Label()
    let x = 3 + (4 * 5)
    temp.Text <- sprintf "x = %d" x
    temp

form.Controls.Add(label)

[<STAThread>]
Application.Run(form)

The output is:

Microsoft (R) F# 2.0 Compiler build 4.0.30319.1 Copyright (c) Microsoft Corporation. All Rights Reserved.

fstest2.fs(1,1): warning FS0062: This construct is for ML compatibility. Conside r using a file with extension '.ml' or '.mli' instead. You can disable this warn ing by using '--mlcompatibility' or '--nowarn:62'.

fstest2.fs(9,2): error FS0010: Unexpected keyword 'let' or 'use' in expression. Expected 'in' or other token.

fstest2.fs(13,1): error FS0597: Successive arguments should be separated by spac es or tupled, and arguments involving function or method applications should be parenthesized

fstest2.fs(9,14): error FS0374: Invalid expression on left of assignment

fstest2.fs(16,1): error FS0010: Unexpected identifier in definition

Guess the error is somewhere in the let label block, but couldn't figure it out.

+7  A: 

If you use "#indent off", then you lose all the simpler whitespace-aware syntax, and have to go back to using e.g.

#indent "off"

open System
open System.Windows.Forms

let label =   
    let temp = new Label() in
    let x = 3 + (4 * 5) in   
    temp.Text <- sprintf "x = %d" x;   
    temp;;

let form = 
    let f = new Form() in
    f.Controls.Add(label);
    f;;

[<STAThread>]   
do Application.Run(form)     

with semicolons and ins and all other kinds of syntactic noise everywhere. You'll probably be happier just having your editor convert tabs to spaces (and having a smart editor that can treat spaces as though they are tabs, e.g. so that backspace can back up one tab-stop).

Brian
+4  A: 

This topic was already discussed in this StackOverflow question. As Brian explains, turning off the "lightweight" syntax means that you'll have to write in the OCaml-compatible syntax.

I believe that in most of the cases, the syntax based on indentation is more readable (and so it is worth switching from tabs to spaces). However, the syntax with additional noise (such as in and ;;) reveals more about the structure of the language, so it may be useful to play with it briefly while learning F#.

The following example shows all the additional things that you need to write:

let add a b c =  
  let ab = a + b in // 'in' keyword specifies where binding (value 'ab') is valid 
  printfn "%d" ab;  // ';' is operator for sequencing expressions 
  c - ab;;          // ';;' is end of a function declaration 

For more discussions, see also this post.

Tomas Petricek
anta40 says “I prefer tabs to spaces”. It is not quite clear why tabs are not allowed for indentation in F# for light syntax? Imagine, somebody has his favorite text editor and some text tools and just habits grown and polished for years for tabs, not for spaces… and now there are only two choices for F#: spaces-light-on, tabs-light-off.
Roman Kuzmin
@anta40 - IIRC, the problem is different editors could use different width tab stops and also mix in spaces. Since changes to the tab width could change the indentation level of any given line, that could also change the meaning of the program itself, resulting in very hard to notice bugs.
James Hugard