3
votes

I checked the relevant spec section and guessed a few tries, but couldn't figure it out. How can I express, for example, the following light syntax recursive let binding using the non-light syntax (on a single line)?

let rec f x = g x 
and g x = f x

(let rec f x = g x and g x = f x gives me "Unexpected keyword 'and' in binding. Expected incomplete structured construct at or before this point or other token." unless I turn the light syntax off, as @Ramon Snir suggested, but surely there is a way to do this while the light syntax is on?)

2
This works fine as it is. FSI handled let rec f x = g x and g x = f x just fine (after #light "off") and compiled correctly. - Ramon Snir
@Karl Knechtel - updated with my main try (other ones just included throwing in, begin, end and brackets around. - Stephen Swensen
@Ramon Snir - very interesting, I'd be surprised if there turned out to be no way to do this while the light syntax is on. - Stephen Swensen
This is a long-standing bug in F#, IMHO. - J D
In the same way "let a = 2 let b = 3" will give you a parse error unless you turn light syntax off. Light syntax sometimes forces you to have line jumps. As Jon says, this "problem" is not new and I don't think there's a workaround (other than insert a line feed... which can be a good thing, after all). - Laurent

2 Answers

3
votes

The same declaration as what @kvb suggests should work at the top-level as well:

#light "off"

module Foo = begin
  let rec f a = g (a + 1)
  and g a = f (a + 1)
end

Maybe the compiler is confused by some other code that follows your declarations?

EDIT: Oh, the problem is slightly different - you wanted to write the recursive declaration on a single line in the #light mode. I couldn't find any way to do that and I think it may not be possible in the #light mode. In practice you can always write multi-line declaration (even in some weird context):

if true && (let rec f x = g x
            and g x = f x in f) 0 then 
    printfn "funny"
0
votes

What you've got is fine, but you're not done yet... The form is let rec [bindings] in [expr]. You've written the bindings, but no body. You simply need to add in and then the expression in which you want the bindings to apply. For example:

#light "off"

let rec even x =
    if x = 0 then true
    else odd (x-1)
and odd x =
    if x = 0 then false
    else even (x-1)
in
    printfn "%b" (even 20)