F# Loading quotation data from an assembly - the explicitlyRegisterTopDefs function - f#

I would like to understand how to retrieve the quotation from a top level function marked with [<ReflectedDefinition>] from an assembly.
It looks like this was done here: Tomas Petricek's blog: Quotation Visualiser Reloaded, but the code (at the very end of the article) makes a simple call to explicitlyRegisterTopDefs to retrieve the top level quoted definition.
I cannot seem to find this function in the latest version of the PowerPack or the F# compiler (I am working with .Net 4.0).
Lots of things happened to have changed since 2006 when the article was written, for example, the Microsoft.FSharp.Quotations.Raw was refactored, as you can see here.
Does anyone know how to capture these top level quotations with the latest versions of the PowerPack / compiler?
Thanks.

We did a lot of stuff like this WebSharper. Basically you do (no powerpack needed):
module QP = Quotations.Patterns
module QDP = Quotations.DerivedPatterns
[<ReflectedDefinition>]
let myFunc x = x + 1
match <# myFunc 1 #> with
| QP.Call(_, QDP.MethodWithReflectedDefinition d, _) ->
printfn "%A" d
| _ ->
printfn "ERROR"
I hope this helps with your scenario.
Note however that it has a ton of problems. Most grievous is that these active patterns throw exceptions from time to time. In addition, they are based on System.Reflection which slows things down enormously. Also, you have to account for unexpected things, like quotation currying not being resolved for you, certain constructor quotations failing, and so on.
For the upcoming WebSharper 2.4 I ended up rewriting the quotation loading code from scratch, using F# compiler sources as the definition of the binary format and avoiding System.Reflection, with great improvements in speed and reliability.

Related

How to invoke Erlang function with variable?

4> abs(1).
1
5> X = abs.
abs
6> X(1).
** exception error: bad function abs
7> erlang:X(1).
1
8>
Is there any particular reason why I have to use the module name when I invoke a function with a variable? This isn't going to work for me because, well, for one thing it is just way too much syntactic garbage and makes my eyes bleed. For another thing, I plan on invoking functions out of a list, something like (off the top of my head):
[X(1) || X <- [abs, f1, f2, f3...]].
Attempting to tack on various module names here is going to make the verbosity go through the roof, when the whole point of what I am doing is to reduce verbosity.
EDIT: Look here: http://www.erlangpatterns.org/chain.html The guy has made some pipe-forward function. He is invoking functions the same way I want to above, but his code doesn't work when I try to use it. But from what I know, the guy is an experienced Erlang programmer - I saw him give some keynote or whatever at a conference (well I saw it online).
Did this kind of thing used to work but not anymore? Surely there is a way I can do what I want - invoke these functions without all the verbosity and boilerplate.
EDIT: If I am reading the documentation right, it seems to imply that my example at the top should work (section 8.6) http://erlang.org/doc/reference_manual/expressions.html
I know abs is an atom, not a function. [...] Why does it work when the module name is used?
The documentation explains that (slightly reorganized):
ExprM:ExprF(Expr1,...,ExprN)
each of ExprM and ExprF must be an atom or an expression that
evaluates to an atom. The function is said to be called by using the
fully qualified function name.
ExprF(Expr1,...,ExprN)
ExprF
must be an atom or evaluate to a fun.
If ExprF is an atom the function is said to be called by using the implicitly qualified function name.
When using fully qualified function names, Erlang expects atoms or expression that evaluates to atoms. In other words, you have to bind X to an atom: X = atom. That's exactly what you provide.
But in the second form, Erlang expects either an atom or an expression that evaluates to a function. Notice that last word. In other words, if you do not use fully qualified function name, you have to bind X to a function: X = fun module:function/arity.
In the expression X=abs, abs is not a function but an atom. If you want thus to define a function,you can do so:
D = fun erlang:abs/1.
or so:
X = fun(X)->abs(X) end.
Try:
X = fun(Number) -> abs(Number) end.
Updated:
After looking at the discussion more, it seems like you're wanting to apply multiple functions to some input.
There are two projects that I haven't used personally, but I've starred on Github that may be what you're looking for.
Both of these projects use parse transforms:
fun_chain https://github.com/sasa1977/fun_chain
pipeline https://github.com/stolen/pipeline
Pipeline is unique because it uses a special syntax:
Result = [fun1, mod2:fun2, fun3] (Arg1, Arg2).
Of course, it could also be possible to write your own function to do this using a list of {module, function} tuples and applying the function to the previous output until you get the result.

Why is "do" allowed inside a function?

I noticed that the following code compiles and works in VS 2013:
let f() =
do Console.WriteLine(41)
42
But when looking at the F# 3.0 specification I can't find any mention of do being used this way. As far as I can tell, do can have the following uses:
As a part of loop (e.g. while expr do expr done), that's not the case here.
Inside computation expressions, e.g.:
seq {
for i in 1..2 do
do Console.WriteLine(i)
yield i * 2
}
That's not the case here either, f doesn't contain any computation expressions.
Though what confuses me here is that according to the specification, do should be followed by in. That in should be optional due to lightweight syntax, but adding it here causes a compile error (“Unexpected token 'in' or incomplete expression”).
Statement inside a module or class. This is also not the case here, the do is inside a function, not inside a module or a class.
I also noticed that with #light "off", the code doesn't compile (“Unexpected keyword 'do' in binding”), but I didn't find anything that would explain this in the section on lightweight syntax either.
Based on all this, I would assume that using do inside a function this way should not compile, but it does. Did I miss something in the specification? Or is this actually a bug in the compiler or in the specification?
From the documentation on MSDN:
A do binding is used to execute code without defining a function or value.
Even though the spec doesn't contain a comprehensive list of the places it is allowed, it is merely an expression asserted to be of type unit. Some examples:
if ((do ()); true) then ()
let x: unit = do ()
It is generally omitted. Each of the preceding examples are valid without do. Therefore, do serves only to assert that an expression is of type unit.
Going through the F# 3.0 specification expression syntax has do expr as a choice of class-function-or-value-defn (types) [Ch 8, A.2.5] and module-function-or-value-defn (modules) [Ch 10, A.2.1.1].
I don't actually see in the spec where function-defn can have more than one expression, as long all but the last one evaluate to unit -- or that all but the last expression is ignored in determining the functions return value.
So, it seems this is an oversight in the documentation.

Why is using the base key word causing this error?

I am trying to do an example for Programming F# by O'Railey, Chris Smith page 53.
It is working with functions returning functions.
This line straight from the book in the VS2013 IDE Editor, FSI and LinqPad4 are giving an error:
Code:
let generatePowerOfFunc base = (fun exponent -> base ** exponent)
Error:
error FS0010: Unexpected keyword 'base' in pattern
What am I missing or is there something the author did not include that needs to be included.
I strongly suspect it's merely a matter of base not being a keyword when the book was written.
Try a different identifier:
let generatePowerOfFunc b = (fun exponent -> b ** exponent)
Assuming you've got the 2009 edition of Programming F#, that would be before F# 2.0 was released (although after 1.0). I'm trying to find out exactly when it was introduced as a keyword...
EDIT: Actually, looking at this version of the spec which was written in 2009, it looks like base was already a keyword at that point. I wonder whether the original code was written significantly before the book was published.
Either way, I think it's reasonable to treat it basically as an error, and using a valid identifier instead should be fine.
EDIT: It's actually listed in the book's errata:
Example 3-3 does not work as-is in VS 2010. "base" is apparently a keyword, so it should have been escaped or there is some voodoo to make it not a keyword that I've missed in the book. Line 2 of the example should look like this:
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
Alternatively, a different variable name should be chosen.
Note from the Author or Editor:
Thanks for the feedback, I must have missed the keyword being marked as reserved late in the product cycle.
In a future version of the book I'll have it read:
let generatePowerOfFunc baseValue = (fun exponent -> baseValue ** exponent);;
base in F# is a keyword, which refers to the parent class.
Either you can use double backticks as follows
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
or just change the name of the argument to something else.

When do you put double semicolons in F#?

This is a stupid question. I've been reading a couple books on F# and can't find anything that explains when you put ;; after a statement, nor can I find a pattern in the reading. When do you end a statement with double semi-colons?
In the non-interactive F# code that's not supposed to be compatible with OCaml, you shouldn't need to ever need double semicolon. In the OCaml compatible mode, you would use it at the end of a top-level function declaration (In the recent versions, you can switch to this mode by using files with .ml extension or by adding #light "off" to the top).
If you're using the command-line fsi.exe tool or F# Interactive in Visual Studio then you'd use ;; to end the current input for F#.
When I'm posting code samples here at StackOverflow (and in the code samples from my book), I use ;; in the listing when I also want to show the result of evaluating the expression in F# interactive:
Listing from F# interactive
> "Hello" + " world!";;
val it : string = "Hello world!"
> 1 + 2;;
val it : int = 3
Standard F# source code
let n = 1 + 2
printf "Hello world!"
Sometimes it is also useful to show the output as part of the listing, so I find this notation quite useful, but I never explained it anywhere, so it's great that you asked!
Are you talking about F# proper or about running F# functions in the F# Interactive? In F# Interactive ;; forces execution of the code just entered. other than that ;; does not have any special meaning that I know of
In F#, the only place ;; is required is to end expressions in the interactive mode.
;; is left over from the transition from OCaml, where in turn it is left over from Caml Light. Originally ;; was used to end top-level "phrases"--that is, let, type, etc. OCaml made ;; optional since the typical module consists of a series of let statements with maybe one statement at the end to call the main function. If you deviate from this pattern, you need to separate the statements with ;;. Unfortunately, in OCaml, when ;; is optional versus required is hard to learn.
However, F# introduces two relevant modifications to OCaml syntax: indentation and do. Top-level statements have to go inside a do block, and indentation is required for blocks, so F# always knows that each top-level statement begin with do and an indent and ends with an outdent. No more ;; required.
Overall, all you need to know is that [O']Caml's syntax sucks, and F# fixes a lot of its problems, but maintains a lot of confusing backward compatibility. (I believe that F# can still compile a lot of OCaml code.)
Note: This answer was based on my experience with OCaml and the link Adam Gent posted (which is unfortunately not very enlightening unless you know OCaml).
Symbol and Operator Reference (F#)
http://msdn.microsoft.com/en-us/library/dd233228(v=VS.100).aspx
Semi Colon:
•Separates expressions (used mostly in verbose syntax).
•Separates elements of a list.
•Separates fields of a record.
Double Semi Colon:
http://www.ffconsultancy.com/products/fsharp_journal/free/introduction.html
Articles in The F#.NET Journal quote F# code as it would appear in an interactive session. Specifically, the interactive session provides a > prompt, requires a double semicolon ;; identifier at the end of a code snippet to force evaluation, and returns the names (if any) and types of resulting definitions and values.
I suspect that you have seen F# code written when #light syntax wasn't enabled by default (#light syntax is on by default for the May 2009 CTP and later ones as well as for Visual Studio 2010) and then ;; means the end of a function declaration.
So what is #light syntax? It comes with the #light declaration:
The #light declaration makes
whitespace significant. Allowing the
developer to omit certain keywords
such as in, ;, ;;, begin, and end.
Here's a code written without #light syntax:
let halfWay a b =
let dif = b - a in
let mid = dif / 2 in
mid + a;;
and becomes with light syntax:
#light
let halfWay a b =
let dif = b - a
let mid = dif / 2
mid + a
As said you can omit the #light declaration now (which should be the case if you're on a recent CTP or Visual Studio 2010).
See also this thread if you want know more on the #light syntax: F# - Should I learn with or without #light?
The double semi-colon is used to mark the end of a block of code that is ready for evaluation in F# interactive when you are typing directly into the interactive session. For example, when using it as a calculator.
This is rarely seen in F# because you typically write code into a script file, highlight it and use ALT+ENTER to have it evaluated, with Visual Studio effectively injecting the ;; at the end for you.
OCaml is the same.
Literature often quotes code written as it would appear if it had been typed into an interactive session because this is a clear way to convey not only the code but also its inferred type. For example:
> [1; 2; 3];;
val it : int list = [1; 2; 3]
This means that you type the expression [1; 2; 3] into the interactive session followed by the ;; denoting the end of a block of code that is ready to be evaluated interactively and the compiler replies with val it : int list = [1; 2; 3] describing that the expression evaluated to a value of the type int list.
The double semicolon most likely comes from OCaml since that is what the language is based on.
See link text
Basically its for historical purposes and you need it for the evaluator (repl) if you use it.
There is no purpose for double semi-colons (outside of F# interactive). The semi-colon, according to MSDN:
Separates expressions (used mostly
in verbose syntax).
Separates
elements of a list.
Separates
fields of a record.
Therefore, in the first instance, ;; would be separating the expression before the first semi-colon from the empty expression after it but before the second semi-colon, and separating that empty expression from whatever came after the second semi-colon (just as in, say C# or C++).
In the instance of the list, I suspect you'd get an error for defining an empty list element.
With regards to the record, I suspect it would be similar to separating expressions, with the empty space between the semi-colons effectively being ignored.
F# interactive executes the entered F# on seeing a double semi-colon.
[Updated to cover F# interactive - courtesy of mfeingold)
The history of the double semicolon can be traced back to the beginnings of ML when semicolons were used as a separator in lists instead of commas. In this ICFP 2010 - Tribute to Robin Milner video around 50:15 Mike Gordon mentions:
There was a talk on F# where someone asked "Why is there double semicolon on the end of F# commands?" The reason is the separator in lists in the original ML is semicolons, so if you wanted a list 1;2;3; and put it on separate lines- if you ended a line with semicolon you were not ending the phrase, so using double semicolon meant the end of the expression. Then in Standard ML the separator for lists became comma, so that meant you could use single semicolons to end lists.

Evaluate Quoted Expression in F#

I hope I haven't missed something obvious, but I've been playing with F# expressions and I want to evaluate quoted expressions on the fly. For example, I want write something like this:
let x = <# 2 * 5 #>
let y = transform x // replaces op_Multiply with op_Addition, or <# 2 + 5 #>
let z = eval y // dynamically evaluates y, returns 7
Is there a built-in F# method which can evaluate quoted expressions, or do I have to write my own?
I've implemented a reflection-based Quotation evaluator as part of Unquote (this is a new feature as of version 2.0.0).
> #r #"..\packages\Unquote.2.2.2\lib\net40\Unquote.dll"
--> Referenced '..\packages\Unquote.2.2.2\lib\net40\Unquote.dll'
> Swensen.Unquote.Operators.eval <# sprintf "%A" (1,2) #>;;
val it : string = "(1, 2)"
I've measured it to be up to 50 times faster than PowerPack's evaluator. This will, of course, vary by scenario. But Unquote is generally magnitudes faster than PowerPack at interpreting expressions.
It also supports many more expressions than PowerPack's evaluator, including VarSet, PropertySet, FieldSet, WhileLoop, ForIntegerRangeLoop, and Quote. In fact, Unquote's evaluator supports all quotation expressions except NewDelegate, AddressSet, and AddressOf all of which I plan on eventually supporting.
No, there's no built-in way to compile F# quotations. With the PowerPack LINQ you can convert SOME quotations to .NET System.Linq.Expressions.Expression, and use that to compile them.
Quotations were made to allow other interpretations of code, such as targeting SQL or a GPU card.
However, in posts on hubfs, it's been hinted at that this is a common request and will be looked at.
You can evaluate an F# quotation using the Eval extension member provided by the FSharp.PowerPack.Linq DLL as follows:
#r "FSharp.PowerPack.Linq.dll"
open Linq.QuotationEvaluation
let f = <#2 + 3#>
f.Eval()
Note that you must open the Linq.QuotationEvaluation namespace to make this extension member available.
There is also a Compile extension member that returns a suspension but it does not appear to improve performance.
Updated in 2016
The Evaluate extension method can now be found in NuGet package FSharp.Quotations.Evaluator
#r "../packages/FSharp.Quotations.Evaluator.1.0.7/lib/net40/FSharp.Quotations.Evaluator.dll"
open FSharp.Quotations.Evaluator
let f = <# 2 + 3 #>
f.Evaluate()
I think the quotations has got a .eval()-method.

Resources