F# Agent.PostAndReply vs Agent.PostAndAsyncReply - asynchronous

I wrote the following two functions:
let requestAsync qry = dispatcher.PostAndAsyncReply (fun chan -> Query (qry chan))
let request qry = qry |> requestAsync |> Async.RunSynchronously
Now I was wondering if I would have any incentive to writing request like this instead:
let request qry = dispatcher.PostAndReply (fun chan -> Query(qry chan))
I wasn't able to decompile the two implementations and as such, I don't know if the second one might be more efficient or whatnot.

The code is at
https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/control.fs
though not exactly perspicuous... I don't think there's much difference; I would call PostAndReply, but they're both doing roughly the same thing and I would not expect a significant difference. (As always, if you care deeply, then measure for your exact scenario.)

Related

Find the instantiation of a class for a type

In Isabelle/HOL, how do I find where a given type was instantiated for a given class? For the sake of this post for example, where real was instantiated as a conditionally_complete_linorder. To justify the question: I might want to know this for inspiration for a similar instantiation, for showing it to someone(s), for Isabelle/HOL practice reading, for curiosity, and so on. My process at the moment:
First, check it actually is: type instantiation real :: conditionally_complete_linorder begin end and see if I get the error message "No parameters and no pending instance proof obligations in instantiation."
Next, ideally before where I'd need to know how i.e. whether it was direct, or implicit via classes C_1[, C_2, C_3, etc]. Then, I would need to find where those instantiations are, either an explicit instantiation real :: conditionally_complete_linorder or the implicit ones for the C_i (same process for either case ofc). I don't know how to find out how, so I have to check for an explicit instantiation, then all possible implicit instantiations.
For explicit, I can do a grep -Ern ~/.local/src/Isabelle2019 -e 'instantiation real :: conditionally_complete_linorder' (and hope the whitespace isn't weird, or do a more robust search :)). Repeat for AFP location. Alternatively, to stay within the jEdit window:
I can find where the class itself was defined by typing term "x::'a::conditionally_complete_linorder" then Ctrl-clicking the class name, and then check if real is directly instantiated in that file with Ctrl-f.
I could then check if it's instantiated where the type real is defined by typing term "x::real" and Ctrl-clicking real, then Ctrl-f for conditionally_complete_linorder in that file.
(If it is in either place it'll be whichever is further down in the import hierarchy, but I find just going through those two steps simpler.) However, if neither two places turn it up then either, for whatever reason, it is explicitly instantiated somewhere else or is implicitly instantiated. For that reason grep is more robust.
If explicit turns nothing up then I check implicit. Looking at the class_deps graph I can see that conditionally_complete_linorder can follow from either complete_linorder or linear_continuum. I can then continue the search by seeing if real is instantiated as either of them (disregarding any I happen to know real can't be instantiated as). I can also check to see if it's instantiated as both conditioanlly_complete_lattice and linorder, which is what I can see conditionally_complete_linorder is a simple (no additional assumptions) combination of*. Repeat for all of these classes recursively until the instantiations are found. In this case, I can see that linear_continuum_topology implies linear_continuum, so kill two birds with one stone with grep -Ern ~/.local/src/Isabelle2019 -e "instantiation.*real" | grep continuum and find /path/to/.local/src/Isabelle2019/src/HOL/Real.thy:897:instantiation real :: linear_continuum.
This process is quite tedious. Less but still quite tedious** would be to get the class_deps graph up and Ctrl-f for "instantiation real" in Real.thy and look for instantiations of: the original class, the superclasses of it, or the classes which imply it. Then in the files each those classes are defined search for "instantiation real". Do this recursively till done. In this case I would have found what I needed in Real.thy.
Is there an easier way? Hope I just missed something obvious.
* I can't Ctrl-click in Conditionally_Complete_Lattices.thy to jump to linorder directly, I guess because of something to do with it being pre-built, so I have to do the term "x::'a::linorder" thing again.
** And also less robust, as it is minus grep-ing which can turn up weirder instantiation locations, then again I'm not sure if this ever comes up in practice.
Thanks
You can import the theory in the code listing below and then use the command find_instantiations. I will leave the code without further explanation, but please feel free to ask further questions in the comments if you need further details or suspect that something is not quite right.
section ‹Auxiliary commands›
theory aux_cmd
imports Complex_Main
keywords "find_instantiations" :: thy_decl
begin
subsection ‹Commands›
ML ‹
fun find_instantiations ctxt c =
let
val {classes, ...} = ctxt |> Proof_Context.tsig_of |> Type.rep_tsig;
val algebra = classes |> #2
val arities = algebra |> Sorts.arities_of;
in
Symtab.lookup arities c
|> the
|> map #1
|> Sorts.minimize_sort algebra
end
fun find_instantiations_cmd tc st =
let
val ctxt = Toplevel.context_of st;
val _ = tc
|> Syntax.parse_typ ctxt
|> dest_Type
|> fst
|> find_instantiations ctxt
|> map Pretty.str
|> Pretty.writeln_chunks
in () end
val q = Outer_Syntax.command
\<^command_keyword>‹find_instantiations›
"find all instantiations of a given type constructor"
(Parse.type_const >> (fn tc => Toplevel.keep (find_instantiations_cmd tc)));
›
subsection ‹Examples›
find_instantiations filter
find_instantiations nat
find_instantiations real
end
Remarks
I would be happy to provide amendments if you find any problems with it, but do expect a reasonable delay in further replies.
The command finds both explicit and implicit instantiations, i.e. it also finds the ones that were achieved by means other than the use of the commands instance or instantiation, e.g. inside an ML function.
Unfortunately, the command does not give you the location of the file where the instantiation was performed - this is something that would be more difficult to achieve, especially, given that instantiations can also be performed programmatically. Nevertheless, given a list of all instantiations, I believe, it is nearly always easy to use the in-built search functionality on the imported theories to narrow down the exact place where the instantiation was performed.

F# collection type for mixed types

This question is coming from someone who is working on making the transition from R to F#. I fully acknowledge my approach here may be wrong so I am looking for the F# way of doing this. I have a situation where I want iterate through a set of XML files, parse them, and extract several values to identify which ones need further processing. My natural inclination is to Map over the array of XML data, exampleData in this case, parse each using the RawDataProvider type provider, and finally create a Map object for each file containing the parsed XML, the Status value from the XML, and the ItemId value.
Turns out that the Map type in F# is not like a List in R. Lists in R are essentially hashmaps which can support having mixed types. It appears that the Map type in F# does not support storing mixed types. I have found this to be incredibly useful in my R work and am looking for what the right F# collection is for this.
Or, am I thinking about this all wrong? This is a very natural way for me to process data in R so I would expect there would be a way to do it in F# as well. The assumption is that I am going to do further analysis and add additional elements of data to these collections.
Update:
This seems like such a simple use case that there must be an idiomatic way of doing this in F# without having to define a Record type for each step of the analysis. I have updated my example to further illustrate what I am trying to do. I want to return an Array of the Map objects that I have analyzed:
type RawDataProvider = XmlProvider<"""<product Status="Good" ItemId="123" />""">
let exampleData = [| """<product Status="Good" ItemId="123" />"""; """<product Status="Bad" ItemId="456" />"""; """<product Status="Good" ItemId="789" />"""|]
let dataResult =
exampleData
|> Array.map(fun fileData -> RawDataProvider.Parse(fileData))
|> Array.map(fun xml -> Map.empty.Add("xml", xml).Add("Status", xml.Status).Add("ItemId", xml.ItemId))
|> Array.map(fun elem -> elem.["calc1Value"] = calc1 elem["itemId"])
|> Array.map(fun elem -> elem.["calc2"] = calc2 elem.["ItemId"] elem.["calc1Value"])
This is what I would consider almost idiomatic here - I'm keeping the same shape as in your example so you can match the two:
let dataResult =
exampleData
|> Array.map(fun fileData -> RawDataProvider.Parse(fileData))
|> Array.map(fun xml -> xml, calc1 xml.ItemId)
|> Array.map(fun (xml, calcedValue1) -> xml, calcedValue1, calc2 xml.ItemId calcedValue1)
What XmlProvider really gives you is not simply xml parsing, but the fact that it generates a strongly typed representation of the xml. This is better than putting the data in a map, in that it gives you stronger guarantees about whether your program is doing the right thing. For instance it wouldn't let you mix up itemId and ItemId as it happened in your code snippet ;)
For the values you calculate in the following steps, you could use tuples instead of a record. In general, records are preferred to tuples as they lead to more readable code, but combining related values of different types into ad-hoc aggregates is really the scenario where using tuples shines.
Now, I said almost idiomatic - I would break up parsing and processing parsed xmls into separate functions, and calculate both calc1 and calc2 results in a single function instead of composing two Array.maps like this:
let dataResult =
parsedData
|> Array.map(fun xml ->
let calced1 = calc1 xml.ItemId
xml, calced1, calc2 xml.ItemId calced1)
If you're coming from R background, you might want to check out Deedle for an alternative approach. It gives you a workflow similar to R in F#.

F#, small type inference / annotation error

This line in F# gives the error that a type annotation may be needed, at "x.Day".
let daysList = List.map (fun x -> x.Day) datesList
But intellisense shows that x is of type DateTime (at "fun x"). And that datesList is of type DateTime list. So I'm perplexed as to why I have to declare the type of x like so and then everything works:
let daysList = List.map (fun (x:System.DateTime) -> x.Day) datesList
The F# compiler generally prefers inferring types from left to right, so if you write it using the pipe operator, it works, assuming that datesList is a DateTime list:
let daysList = datesList |> List.map (fun x -> x.Day)
Why, then, can IntelliSense determine that x is a DateTime? Beats me, but in my experience it's fairly common that IntelliSense sometimes disagrees with the compiler.
BTW, that left to right rule doesn't always seem to be strict, either. I often have to experiment a bit before I get everything right.

Exact usage of Async.Sleep() in F#

I have a question:
I have problem in usage Async.Sleep() method in F#. This is a piece of code in my program:
if (newAngle <> currentAngle) then
if (newAngle = 0) then
Motor(MotorPort.OutA).SetSpeed(100y)
angle1 <- Motor(MotorPort.OutA).GetTachoCount()
**Async.Sleep(20)**
angle2 <- Motor(MotorPort.OutA).GetTachoCount()
speed <- abs(angle2 - angle1)
distance <- abs(newAngle - angle2)
if (speed > 11) then
pwr <- 20L + int64 distance
if (pwr < 100L) then
Motor(MotorPort.OutA).SetSpeed(sbyte pwr)
while (distance > 30 || angle2 <> angle1) do
angle1 <- Motor(MotorPort.OutA).GetTachoCount()
**Async.Sleep(20)**
angle2 <- Motor(MotorPort.OutA).GetTachoCount()
speed <- abs(angle2 - angle1)
distance <- abs(newAngle - angle2)
if (speed > 11) then
pwr <- 20L + int64 distance
if (pwr < 100L) then
Motor(MotorPort.OutA).SetSpeed(sbyte pwr)
Motor(MotorPort.OutA).Off() //? off
**Async.Sleep(300)**
I have used Async.Sleep() function in some places in my code. But unfortunately, when I use Async.Sleep() method I get this error:
This expression was expected to have type unitbut here has type Async<unit>
How can I solve this problem?
You need a do! before the call to Async.Sleep, i.e.
async{
...
do! Async.Sleep(time * 1000)
...
}
How to research this on your own next time:
Bing "Async.Sleep"
First result - MSDN docs for F# Async.Sleep
Look at example code.
Async.sleep gives back some "async" code.
The "async" computation expression builder allows to inject computations to a new type, async<_>, and weave such computations in a way which does not block a single thread, by relying on the threadpool and knowing how to suspend (and resume !) computations in a efficient way.
The bottom line is that the main benefit is the controlled weaving (and - different aspect - controled execution) of such computations.
If you just need one Async instruction, there is no weaving, and no benefit in using the async<_> type. As suggested, you propably want to use the Thread.Sleep
The best way to learn about those async is to unsugar the async computation expression into its succession of callback. every computation expression is compiled to that form.
Then you can look at the specific operations invoked, which are specific to the async computation expression builder.
--
Unfortunately, while F# async make everything possible to make it simple to use, such feature is nonetheless not trivial, and require some time to understand.
I suggest you look at it as a subject on its own first, and not go for a quick fix.
The good part is that it is quite instructive to understand this technique as it uses more general mechanism like computation expression !
Async.Sleep returns an async computation. All you have to do is just run it and wait until it finishes:
Async.Sleep(5000) |> Async.RunSynchronously
Try the following:
open System.Threading
//and wherever requires write the below mentioned code
Thread.Sleep(20000) //20000 in Milliseconds unit

Opa: What Is the Fastest Way to Reverse a String?

What is the most performant way to implement a "reverse a string" function in Opa?
I am aware of String.reverse(). It does get the job done, but its source code is bound to some external function. I want to understand what the best (fastest) tools are for reordering a string.
So, for example, this works, but isn't particularly fast:
reverse(s:string) =
p = parser
| x=(.) xs=(.*) -> Text.concat(reverse(Text.to_string(xs)), x)
| x=(.*) -> x
Parser.parse(p, s)
How can I make this perform better?
Edit: Another Implementation Based on akoprowski's Answer
I think this is what he has in mind. This one is much faster than the parser version, but the built-in String.reverse is the way to go if all you need to do is reverse a string.
reverse_list(l:list(string)):list(string) =
match l with
| [x|xs] -> reverse_list(xs) ++ [x]
| _ -> []
reverse_string(s:string) =
string_list = List.init((i -> String.get(i, s)), String.length(s))
String.flatten(reverse_list(string_list))
Edit: The Above Implementation Is Not Ideal
Check out the accepted answer for a better option.
Why don't you want to use String.reverse? (which is the preferred way of reversing a string). Or is that just an exercise?
I'd suggest using List.init to generate a list of characters, String.get (to get n'th character of the string) and String.flatten to convert a list of characters back to a string.
That should be faster than the parsing-based approach, which btw. has quadratic complexity so no wonder it's slow.
Edit: the solution I had in mind:
reverse_string(s:string) =
n = String.length(s)
rev_list = List.init((i -> String.get(n - i - 1, s)), n)
String.flatten(rev_list)

Resources