Why doesn't Console.Readline work but Console.Readline() does?
Solution 1
If you use
let s = Console.ReadLine
you are only building a delegate that points to the ReadLine function. You need to say
let s = Console.ReadLine()
to actually execute the function. This is just like C# syntax, except type inference means you don't get a compiler warning.
Solution 2
What do you mean by "it isn't being honored"? Here's a small console app I've just written in VS2010b1, and it works fine:
open System
let line = Console.ReadLine()
Console.WriteLine("You wrote {0}", line)
// Just to make it pause
let unused = Console.ReadLine()
Are you trying to run the code from F# Interactive within Visual Studio? If so, that may be the issue, as Brian's post explains.
However, I haven't seen the same problem when using F# Interactive from the command line. Here's a complete transcript of a session:
Microsoft F# Interactive, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.16, compiling for .NET Framework Version v4.0.20506
Please send bug reports to [email protected]
For help type #help;;
> open System;;
> let line = Console.ReadLine();;
Hello world
val line : string = "Hello world"
Running Brian's looping code from F# Interactive didn't show the same problem.
Bottom line: It seems like this is broken in F# Interactive in Visual Studio, but not when running interactively from the command line or in a full console app.
Solution 3
I don't have a Beta1 box handy, but I know that in the past we've had a bug where ReadLine() would see the background commands that communicate between the interactive UI and the background process that runs your F# code. It may be interesting to investigate what
let Foo max =
let rec Loop i =
if i < max then
let line = System.Console.ReadLine()
printfn "line = %s" line
Loop (i+1)
Loop 1
Foo 12
prints when you highlight it and 'Send to Interactive'. I think possibly you'll see a few unexpected interesting lines, followed by lines you type into the window.
Comments
-
Jonathan Allen almost 2 years
How do you use Console.Readline in F#? Unlike Console.Writeline, it isn't being honored when I call it.
-
Jon Skeet almost 15 yearsYup, that looks like it could be the problem: when I try that in beta 1, the first line written out is just "line = "
-
Jon Skeet almost 15 yearsHmmm... that's odd. Is this with the version installed with VS2010b1?
-
Jonathan Allen almost 15 yearsWeird. Yesterday I couldn't get it to work no matter what I tried. Now I can't get it to fail, again no matter what I try.
-
Jonathan Allen almost 15 yearsThe difference is that you are putting empty parens on the end of the ReadLine call and I wasn't.
-
Jonathan Allen almost 15 yearsI figured it out. "Console.ReadLine()" works. "Console.ReadLine" is silently ignored because it is just building a delegate.
-
Jon Skeet almost 15 yearsAh, I assumed you were actually calling it as you mentioned Console.WriteLine() :) Anyway, glad the mystery is solved!
-
YotaXP almost 15 yearsYup. Console.ReadLine is a "unit -> string" value. By adding the (), you're passing in the 'unit' that it is expecting as an argument.
-
Jonathan Allen almost 15 yearsSo did I. I'm used to VB where the parens are optional and you have to indicate when you want the function itself.
-
Jon Skeet almost 15 yearsAh... I wondered whether that might be the case, but felt foolish suggesting it :)
-
Jonathan Allen almost 15 yearsGiven how subtle the difference is, I'm sure you will get many more chances to ask that question.
-
Erik Forbes almost 15 years"let unused = Console.ReadLine()" would be more F# idiomatic as "Console.ReadLine() |> ignore" - this removes the need for a useless 'let' statement and handles ignoring the return value.
-
Robert Jeppesen about 13 years+1 - This behaviour could be made clearer by requiring a space in front of the (), just like any other argument to a function.
-
Arturo Hernandez about 9 yearsYou would get a compiler warning! When you make use s. It sounds like you meant to write
Console.ReadLine() |> ignore
. I would argue that it is C# that does not check whether the output of a function is either captured or ignored.