This F# code is failing to compile:
let DoubleString (str : string) = str + str
let ExampleSetString (str : string byref) =
async {
str <- DoubleString str
return 1
}
I get the following error message on the line str <- DoubleString str:
The byref-typed variable 'str' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions
I must take a byref variable, pass it into some pure functions within a computation expression and then set the value of this byref variable. How can I do this?
Dotnet restricts storing byref variables into fields, because byref can point at
array element (&ar[42])
field of object (&myObject.MyField)
local variable (&myLocalVar)
unmanaged memory (&(System.Runtime.CompilerServices.Unsafe.AsRef<myStruct> myVar))
probably more
This leads to a lifetime problem: reference can outlive variable it's pointing at. It won't happen with case 1, but can happen with all other items. For example given function Foo calling Bar and passing value by reference will produce this stack
Baz function Foo function Bar function
/ \ / \ / \
--------------|---a----------|----b---------
Foo have called Bar and passed it a as reference &a. Bar have stored address of a into variable b. This means that b is byref-variable, updates on this variable will change value in a. When function completes it's work, memory is freed and can be reused by other function.
Baz function Egg function
/ \ / \
--------------|---c----------
Baz have called Egg function, and now at memory where was a now lies c. Attempting to change reference to a now can cause all sort of memory problems, from AccessViolation (also known as Segmentation Fault in Linux), to data corruption. Worst thing that can happen when memory is corrupted, is for program to continue it's work.
That's the reason why byref variables cannot be captured into closures, which are produced by computation expression.
Now let's return to actual problem - store string intro Azure blob. I'm not familiar with it, but I've found example for this, which can be adapted to following
let DoubleString (str : string) = str + str
let ExampleSetString (containerClient : BlobContainerClient) (str : string) =
task {
let client = containerClient.GetBlobClient("path to where to store")
let doubled = DoubleString str
do! client.UploadAsync(BinaryData.FromString(double), ?overwrite=true)
}
Related
i'm trying to develop the algorithm W in f# for type inference, but i would like to understand how to write the function for generating fresh variables properly.
Actually my function is
let counter = ref -1
let generate_fresh_variable () : string =
let list_variables = ['a' .. 'z'] |> List.map string
counter.Value <- !counter + 1
list_variables.Item(!counter)
but i'm not satisfy with this solution, someone can give me other better ideas?
If you really want to do this with an impure function, I would write it like this:
let mutable counter = -1
let generate_fresh_variable () =
counter <- counter + 1
counter + int 'a'
|> char
|> string
Notes:
Reference cells are obsolete. If you need impurity, use mutable variables instead. (Alternatively, if you really want to stick with a reference cell, the canonical way to update it is with :=, rather than assigning directly to the underlying Value.)
There's no need to maintain a list of potential variable names (and there's especially no need to rebuild the entire list each time you generate a fresh variable).
What happens if you need more than 26 variables?
If you wanted to use some more sophisticated F# tricks, you could create an inifinte sequence of names using a sequence expression (which makes it very easy to handle the looping and dealing with >26 names):
let names = seq {
for i in Seq.initInfinite id do
for c in 'a' .. 'z' do
if i = 0 then yield string c
else yield string c + string i }
A function to get the fresh name would then pick the next name from the sequence. You need to do this using the underlying enumerator. Another nice trick is to hide the state in a local variable and return a function using lambda:
let freshName =
let en = names.GetEnumerator()
fun () ->
ignore(en.MoveNext())
en.Current
Then just call freshName() as many times as you need.
I'm learning me some F#, and I'm trying to figure out how constructors work.
I want to write a class that takes some input data, parses it, and makes the results available to the outside world via member variables. The parsing process is non-trivial, so I want to create some local variables along the way, but how can I do that without them becoming private member variables, as well? AFAICT, using let to create a private member variable is almost the same as using member private, but I don't want these temporary variables to pollute the object's namespace.
This is the best I've been able to come up with, so far:
type MyClass( inputData ) =
let _parsedData =
// simulate expensive parsing of the input data
let work = sprintf "< %s >" inputData
sprintf "[%s]" work
member this.parsedData = _parsedData
member this.dump () =
// this doesn't compile (as expected)
//printfn "work = %s" work
// I want this to *not* compile (because _parsedData is a local variable in the constructor)
printfn "_parsedData = %s" _parsedData
[<EntryPoint>]
let main argv =
let obj = MyClass "hello, world!"
printfn "obj.parsedData = %s" obj.parsedData
obj.dump()
0
But _parsedData becomes a private member variable, which is not necessary since it's just a temporary working variable, and the final value is stored in this.parsedData. The SO post I linked to above suggests that variables created using let will act as local variables and be discarded, as long as they are not referenced in other members, but the act of defining this.parsedData to return _parsedData is enough to keep _parsedData alive.
I could use lazy evaluation:
let _parsedDataLazy = lazy (
// simulate expensive parsing of the input data
let work = sprintf "< %s >" inputData
sprintf "[%s]" work
)
member this.parsedDataLazy = _parsedDataLazy.Value
but this doesn't really help, since it still has the problem of _parsedDataLazy becoming a private member variable (although in this case, it makes sense). This approach also means keeping inputData alive until the first time parsedDataLazy is called, which may not be desirable/possible.
I also thought of using val to define the member variable, then execute the parsing code to populate it, but do bindings have to appear before any member's :-/
I just want to be able to use local variables in a constructor, to calculate a value, then store it in the object. Why does let create a private member variable, given that there's already a way of doing that?! The purpose of a constructor is to initialize the object being created, it's just a function, so I don't get why there are these special restrictions on when code can be executed, or different behaviour (e.g. if I use let to define a new variable in a member function, it doesn't get hoisted into the object as a member variable).
As an aside, if I create a private member variable in the constructor using let, like this:
let _foo = 42
then I access it like this:
let member this.printFoo () =
printfn "_foo = %s" _foo // no "this"
But if I create it like this:
member private _foo = 42
then I access it like this:
let member this.printFoo () =
printfn "_foo = %s" this._foo // uses "this"
This different syntax suggests that the former is creating a closure over the constructor, and keeping the _foo variable alive for the life of the object, rather than _foo actually being member of the object. Is this what's actually happening?
To answer #konst-sh's question "why do you think it should be evaluated on every call?", I don't think it should, but that's not what I'm seeing.
My understanding is that for the code below, the 3 statements that make up parsedData are an expression, that evaluates to a string (the output of sprintf), that is stored in a member variable.
type MyClass( inputData ) =
member this.parsedData =
// simulate expensive parsing of the input data
printfn "PARSE"
let work = sprintf "< %s >" inputData
sprintf "[%s]" work
[<EntryPoint>]
let main argv =
let obj = MyClass "hello, world!"
printfn "CONSTRUCTED"
printfn "obj.parsedData = %s" obj.parsedData
printfn "obj.parsedData = %s" obj.parsedData
0
But when I run it, I get this:
CONSTRUCTED
PARSE
obj.parsedData = [< hello, world! >]
PARSE
obj.parsedData = [< hello, world! >]
I would expect to see this:
PARSE
CONSTRUCTED
obj.parsedData = [< hello, world! >]
obj.parsedData = [< hello, world! >]
Stepping through in VSCode also confirms that the 3 statements get executed twice. But parseData is not a function, right? For that, I would need to define it like this:
member this.parsedData () =
...
It feels like I'm missing something fundamental here... :-)
So I have this function that calculates the frequency percentage of each letter given a string. this function is called "frequency" and utilizes other helper functions that I've wrote ("count", "lowerCases", and "percent"). But when I try to return my result, I keep getting a mismatch error. Here is my code below:
let frequency(str:string) : float =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
System.Console.WriteLine(frequency"hello world")
I keep getting this error:
This expression was expected to have type float but here has type unit
How can I fix this type mismatch error? I've already tried setting my result to a different variable and calling that variable, but that didn't work.
You've declared the function as returning a float:
let frequency(str:string) : float =
However, your function doesn't return a float, it just prints one out:
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
The printf function returns unit, meaning that it effectively has no return value (it has a constant return value of the singleton type unit).
There are two things that I see you needing to fix here. You need to return a value from the function (by having it be the value of the last line), and I think you will want your return type to be a list or a map instead of a single value (else, how would you know two which letter the frequency applies)?
You can achieve this result by just calling your percent function from List.map, and then making Map of the list:
let frequency(str:string) : Map<char, float> =
['a'..'z']
|> List.map (fun letter -> letter, (percent ((count letter str) (lowerCases str))))
|> Map.ofList
An F# function binds a single value of the single expression in its body (the one which comes last after all let-bindings, simply speaking. In your case, this expression is
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
It has the type unit, meaning it does not return anything useful but a special value (), while the let frequency ... : float = binding says that it returns a float. Hence the error.
printf already prints to console. What you want is probably
let frequency(str:string) : unit =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
do frequency "hello world"
It is idiomatic to omit the : unit annotation in such a function, and let the compiler infer the return type. This code does not shine the F# glory, naturally, but does the job.
As it appears you are learning the language, here's an exercise, maybe for the future. Your function lumps together computing the letter frequencies and printing them, and functional programming is all about composition. What if you want to display the result in a window instead of printing it to console, or format it differently? Try to write two functions, one returning a data structure with the letter frequencies, and another printing it.
I wrote the following code to test some MonteCarlo code in F#.
My problem is I only see the random numbers and the "oi" once in my console. I call two times the oneRun function, but it looks that it only runs once.
Here is the code:
let genRandomNumbers count =
let rnd = System.Random()
printf "oi "
List.init count (fun _ -> rnd.NextDouble ())
let oneRun =
let numberofClicks = 0
let randomNumber = genRandomNumbers 50
let action numberofClicks random = if random <= 0.10
then numberofClicks+1
else numberofClicks
randomNumber |> Seq.iter (printf "%f ")
randomNumber |> List.fold action numberofClicks
[<EntryPoint>]
let main argv =
let a = oneRun
printf "%d " a
let b = oneRun
printf "%d " b
let key_info = Console.ReadKey()
0 //
Any hints? Ideas?
To expand a little on Mankarse's correct comment, the F# syntax for defining values and functions looks very similar, so it's easy to get confused between them.
This is a value:
let sum = 42
This is a function:
let addThree x = x + 3
Both values and functions can have blocks following them, not just single lines:
let sumWithSideEffects =
// This will only be evaluated once
printfn "Side effect happens here"
42
let addThree x =
// This will run every time you call the function
let result = x + 3
printfn "Added three to %d and got %d" x result
result
A let declaration that just declares a name is a value. Values are only evaluated once, so any side effects in the value will happen just once. Exactly when they happen is not defined precisely by the language spec, so you can't count on when the side effects will happen. Functions, on the other hand, are evaluated every time the function is called.
Now, when you have a function that takes no parameters, how do you declare it? Well, you declare it by giving it a parameter, but a parameter that doesn't matter. Specifically, you declare that it takes a parameter of type unit. The unit type is a special type in F#. It basically corresponds to an empty tuple, and is written as ().
Think about the empty-tuple type for a minute. If you have a tuple of two bool values, how many possible values can this tuple have? Four: it could be (false, false), or (false, true), or (true, false), or (true, true). If you have a tuple of just one bool, it could have two values: (true) or (false). If you have a tuple of zero values (of whatever type: bool, int, string, doesn't matter), then there's only one possible value it could have: (), the empty tuple. And since that's a type with only one possible value, that's why it's called the unit type.
So if you want a function rather than a value, but that function doesn't need to take any meaningful parameters, you define it like this:
let myFunction () =
printfn "I'm being called purely for the side effects"
Note how I put a space between the function name and the unit parameter. You don't actually have to have that space there — it's perfectly legal to write let myFunction() = ... — but I want you to see that the () is not just function-declaration syntax, it's an actual value of an actual type. This distinction becomes important when you start doing advanced things with functions, so I want you to be clear about it now.
BTW, normally you'd have a parameter name in your function declaration rather than a value, but the unit type is treated specially: since there's only one possible value of unit, you already know what value your function will be called with, so you don't really need to assign that to a name anyway. So F# lets you declare a function whose input type is unit by just having a () in the parameter list, instead of making you choose a name that you'd never actually use in the function body.
I hope this clears things up for you.
Consider the following F#:-
type TestClass() =
let getValFromMap m k = Map.find k m
let addToMap map k i = map |> Map.add k i
let mutable someMap : Map<string,int> = Map.empty
let getValFromMapPartial key = getValFromMap someMap key
let getValFromMapPartialAndTacit = getValFromMap someMap
member this.AddThenGet() =
someMap <- addToMap someMap "A" 10
let value = getValFromMapPartial "A"
printfn "Value from partial = %i" value // prints out
let value = getValFromMapPartialAndTacit "A" // throws
printfn "Value from partial and tacit = %i" value
[<EntryPoint>]
let main argv =
let test = TestClass()
test.AddThenGet()
0
Functions getValFromMapPartial and getValFromMapPartialAndTacit are, to my mind, identical. F# says they have the exact same type: (string -> int). And yet they behave very differently, and they are compiled very differently. Decompiling using dotPeek, I see that getValFromMapPartial is a method, whereas getValFromMapPartialAndTacit is a field that is initialized in the ctor.
F# does not complain about getValFromMapPartialAndTacit, even on the highest warning level (both in VS 2012 and 2013). And yet calling this function in my sample above fails, presumably because it has wrapped the initial, empty version of the someMap, despite its mutability.
Why is there a difference between these two functions? Should there be a warning from F# that the tacit / point-free version might fail?
The F# compiler distinguishes between let-bindings of functions, which have parameters, and values, which do not have parameters.
Value definition: A binding like let a = ... is a value definition. Its body is evaluated eagerly, "where it is", before the evaluation of anything further down the code.
Function definition: A binding like let f x = ... is a syntactic function definition, the contents of which are evaluated when the function is called.
Since someMap refers to a mutable variable, using this variable inside a function definition means reading from the variable when the function is called. However, the usage in getValFromMapPartialAndTacit reads the value at the moment of declaration.
This behavior does not stop a value from being a function. You could just as well write let f = fun x -> ... to declare a function, and ... would again be part of a function definition. However, if you were to add definitions in between the = and fun, they would be evaluated at the point of the definition of f, not when it is called.
In the question's comments, the same problem occurs with someMap being a mutable reference cell. This is the same problem. The function, as rewritten by Andrew for a mutable reference cell:
let getValFromMapPartialAndTacit = getValFromMap !someMap
Here, the dereference operator (!) is applied when the value is bound, not when the function is called. it is equivalent to:
let mapRightNow = !someMap
let getValFromMapPartialAndTacit = getValFromMap mapRightNow
getValFromMapPartial is a true syntactic function. Its signature is val getValFromMapPartial : key:string -> int. Whenever it is called, it uses the current value of someMap. That's why it works in your example; it accesses the version of someMap who has an entry.
On the other hand, getValFromMapPartialAndTacit is a lambda-computing function. Its signature is val getValFromMapPartialAndTacit : (string -> int) (notice the parentheses). The lambda has a compiler-generated closure, which contains the version of someMap at the time the lambda was computed. That's why it does not work in your example; it always acesses the same, original version of someMap who has no entry.