F# / Ionide in Visual Studio Code, max script length to FSI? - f#

I am having a problem sending F# scripts to F# Interactive using Ionide in Visual Studio Code.
I am using the "FSI: Send Selection" command using Alt+Enter.
This works fine for smaller scripts, but with script length exceeds a certain limit (approx 1.5kb), it no longer sends to FSI. There is no error shown in FSI, nothing happens. Reducing the selection size below this limit restores original behaviour, until it exceeds it again.
I've not found any clues online, and would appreciate any hints for how to resolve/investigate this. I've uninstalled and reinstalled Ionide & Visual Studio Code, without any effect.
Here is an example script that works, but adding even one more character takes it over the limit:
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "1234567890123456789012345678901234567890123456789012345678901234567890"
printfn "12345678901234567890"

Related

syntax issue around kprintf in F#

I have a project using NLog and there is a wrapper around the logger, in order to turn logging off in some areas:
member this.SetQuiet q = quiet <- q
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) format
member this.Debug format = Printf.kprintf (fun s -> if not quiet then logger.Debug(s)) format
member this.Info format = Printf.kprintf (fun s -> if not quiet then logger.Info(s)) format
member this.Warn format = Printf.kprintf (fun s -> if not quiet then logger.Warn(s)) format
member this.Error format = Printf.kprintf (fun s -> if not quiet then logger.Error(s)) format
member this.Fatal format = Printf.kprintf (fun s -> if not quiet then logger.Fatal(s)) format
this works quite well, but I have an issue:
logger.Info "hello"
logger.Info <| "hello"
will work properly, whereas:
"hello" |> logger.Info
will not compile with this error:
typecheck error The type 'string' is not compatible with the type 'Printf.StringFormat<'a,string>'
can someone explain me why this fails? the order kprintf-continuation-format should still be respected here, no?
Is there a workaround for this? the reason is that I'm trying to do a 'tee' to log messages in a non verbose way (the tee just applies a function and then returns the original parameter):
"my messsage"
|> tee logger.Info
|> Result.Ok
That happens because printf and similar methods uses formatting. It allows type-safe usage of these method. For example printfn "%d" enforces integer as parameter
printfn "%d" 3
printfn "%d" 3.14 // error
printfn "%s %f" enforces string and float.
printfn "%s %f" "Hello" 3.14
printfn "%s %f" '3' 14 // error
This means that you should change methods this way (added "%s")
member this.Trace format = Printf.kprintf (fun s -> if not quiet then logger.Trace(s)) "%s" format

Why does iterating previously read-in sequence trigger a new read?

In this SO post, adding
inSeq
|> Seq.length
|> printfn "%d lines read"
caused the lazy sequence in inSeq to be read in.
OK, I've expanded on that code and want to first print out that sequence (see new program below).
When the Visual Studio (2012) debugger gets to
inSeq |> Seq.iter (fun x -> printfn "%A" x)
the read process starts over again. When I examine inSeq using the debugger, inSeq appears to have no elements in it.
If I have first read elements into inSeq, how can I see (examine) those elements and why won't they print out with the call to Seq.iter?
open System
open System.Collections.Generic
open System.Text
open System.IO
#nowarn "40"
let rec readlines () =
seq {
let line = Console.ReadLine()
if not (line.Equals("")) then
yield line
yield! readlines ()
}
[<EntryPoint>]
let main argv =
let inSeq = readlines ()
inSeq
|> Seq.length
|> printfn "%d lines read"
inSeq |> Seq.iter (fun x -> printfn "%A" x)
// This will keep it alive enough to read your output
Console.ReadKey() |> ignore
0
I've read somewhere that results of lazy evaluation are not cached. Is that what is going on here? How can I cache the results?
Sequence is not a "container" of items, rather it's a "promise" to deliver items sometime in the future. You can think of it as a function that you call, except it returns its result in chunks, not all at once. If you call that function once, it returns you the result once. If you call it second time, it will return the result second time.
Because your particular sequence is not pure, you can compare it to a non-pure function: you call it once, it returns a result; you call it second time, it may return something different.
Sequences do not automatically "remember" their items after the first read - exactly same way as functions do not automatically "remember" their result after the first call. If you want that from a function, you can wrap it in a special "caching" wrapper. And so you can do for a sequence as well.
The general technique of "caching return value" is usually called "memoization". For F# sequences in particular, it is implemented in the Seq.cache function.

Possible to pass Printf.TextWriterFormat to MailBoxProcessor?

I am building a parallel unit test runner using MailBoxProcessor.
I need to queue up print statements for a test, so I can print them once a test is finished. I know how to send a string and build up a list so I can print them, but that forces me to use sprintf and pipe it into my print function and is not as clean as I would like.
[1..200]
|> List.iter (fun i ->
sprintf "Test %i" i &&& fun ctx ->
ctx.printfn <| sprintf "A guid %A" (ng())
ctx.printfn <| sprintf "I am test %i" i
ctx.printfn <| sprintf "A guid %A" (ng()))
You can see the full code here:
https://github.com/lefthandedgoat/prunner/blob/master/Program.fs#L36-L41
And see that ctx is an object with a printfn method that takes a string and posts it to a single mailbox that queues up messages until a tests is done, then loops over them and prints them.
My goal is to have the ctx.printfn look like this
[1..200]
|> List.iter (fun i ->
sprintf "Test %i" i &&& fun ctx ->
ctx.printfn "A guid %A" (ng())
ctx.printfn "I am test %i" i
ctx.printfn "A guid %A" (ng()))
Your question isn't entirely clear, but you may be able to achieve your goal via kprintf:
member x.printfn fmtStr =
Printf.kprintf (fun msg -> reporter.Post(Print(msg, x.TestId))) fmtStr

Learning F# with style [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
When passing a function to another function which should calculate the result and then pass that value as an argument to another function, I've discovered that I could "compose" the following code in 5 different ways.
let testnum testFun =
testFun 4
printfn "result: %b" (testnum (=) 0)
printfn "result: %b" <| testnum (<) 0
printfn "result: %b" (testnum <| (>=) 0)
testnum <| (=) 0 |> printfn "result: %b"
printfn "resutl: %b" << testnum <| (<>) 0
I do like the style without parentheses more but now I'm wondering, is there a preferred style assuming my goal is readability and supportability of my code?
For your example I would have picked the first one:
printfn "result: %b" (testnum (=) 0)
The second one is passable:
printfn "result: %b" <| testnum (<) 0
The others are too contrived, they look like exercise in obfuscation.
I do use "backward" pipe operator exclusively in two situations:
when I have a type constructor that would need nested parentheses otherwise, so Some <| Foo ("bar", "baz") instead of Some (Foo ("bar", "baz"))
when I want to pass a single anonymous function as a last argument - it communicates nicely where the action is at:
lock sync <| fun () ->
...
For what is worth, if there are multiple anonymous functions passed as arguments, I would usually parenthesize each one of them instead (the notable exception being when one of them is a few characters long one liner and the other has multiple lines - then I would still go with the above syntax).
As for pipelining, I would usually go with |> for longer pipelines, and use function composition >> for shorter ones, when I don't need to refer to the argument again in the body of the function.
I don't think I would ever put |> and <| in the same line without parenthesizing one of them. It just looks odd.
Prefer pipe |>, this help with inference and readability
(=) 3 |> testnum |> printfn "result: %b"
you can easy break it on multiple lines
(=) 3
|> testnum
|> printfn "result: %b"
if arguments are few, you can pass them directly
testnum (=) 4 |> printfn "result: %b"
but use pipe |> or composition >> like g x |> f or x |> g |> f instead of nested function call f(g(x)), is more idiomatic. This also help with inference, for example instead of the . operator
open System.Linq
let double x = x * 2
let double1 items = items |> Seq.map double
[1;2;3] |> double1 |> printfn "%A"
//this doesn't compile,
//error: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed ..
//
// let double2 items = items.Select(double)
// [1;2;3] |> double2 |> printfn "%A"
let double3 (items:seq<_>) = items.Select(double)
[1;2;3] |> double3 |> printfn "%A"
example: https://dotnetfiddle.net/K0u3NQ

printfn "%A" "c" using F#

By running printfn "%A" "c", I get "c".
By running printfn "%s" "c", I get c.
Why the difference? The same goes for char.
The %A specifier tries to hint at object types - the "c" is it trying to show it is a string. When you do %s the compiler knows you want to print a string so it doesn't print the quotes
Because printfn "%A" uses reflection, it displays results the same as values automatically printed out by F# Interactive. On the other hand, %s is for strings only, and it shows contents of strings.
The generic case of "%s" is "%O" when ToString methods are used. The %A specifier is slow, but helpful for structural types and types without overridden ToString methods.

Resources