[<ReflectedDefinition>]
let rec x = (fun() -> x + "abc") ()
The sample code with the recursive value above produces the following F# compiler error:
error FS0432: [<ReflectedDefinition>] terms cannot contain uses of the prefix splice operator '%'
I can't see any slicing operator usage in the code above, looks like a bug... :)
Looks like this is the problem with the quotation via ReflectedDefinitionAttribute
only, normal quotation works well:
let quotation =
<@ let rec x = (fun() -> x + "abc") () in x @>
produces expected result with the hidden Lazy.create
and Lazy.force
usages:
val quotation : Quotations.Expr<string> =
LetRecursive
([(x, Lambda (unitVar,
Application
(Lambda (unitVar0,
Call (None,
String op_Addition[String,String,String](String, String),
[Call (None,
String Force[String](Lazy`1[System.String]), // `
[x]), Value ("abc")])),
Value (<null>)))),
(x, Call (None, Lazy`1[String] Create[String](FSharpFunc`2[Unit,String]), [x])),
(x, Call (None, String Force[String](Lazy`1[String]), [x]))], x) // `
So the question is: is this an F# compiler bug or not?
An f-stop is expressed as a fraction, with “f” as the numerator and the f-stop number as the denominator. The aperture size reads inversely to its corresponding f-number: The smaller the f-number, the larger the aperture. The larger the f-number, the smaller the aperture.
Aperture controls the brightness of the image that passes through the lens and falls on the image sensor. It is expressed as an f-number (written as “f/” followed by a number), such as f/1.4, f/2, f/2.8, /f4, f/5.6, f/8, f/11, f/16, f/22, or f/32.
The lowest f-stop available is f/0.7. It belongs to Zeiss Planar 50mm, a lens used by NASA to film the moon, and Stanley Kubrick to make a film at candlelight. However, most photo lenses go as low as f/2, fewer go to f/1.2, and only a few reach f/0.95. The largest f-stop available is f/45.
Here's the aperture scale. Each step down lets in half as much light: f/1.4 (very large opening of your aperture blades, lets in a lot of light) f/2.0 (lets in half as much light as f/1.4) f/2.8 (lets in half as much light as f/2.0)
I'd think that this may be caused by the treatment of recursive values in F#. As a workaround, you can turn the recursive reference into a parameter:
[<ReflectedDefinition>]
let foo x = (fun() -> x + "abc") ()
// To construct the recursive value, you'd write:
let rec x = foo x
The last line is of course invalid (just like your original code), because you're creating an immediate recursive reference, but it should give you the idea - in reality, you'd probably enclose x
in a lambda function.
EDIT Originally, I thought that the problem may be as below, but I'm not sure now (see comments).
It looks more like a (probably known) limitation to me than an unexpected bug. There is an important difference between the two versions of the code you wrote - in the first case, you're binding a public value (visible to .NET) named x
while in the second case, x
is just a symbol used only in the quotation.
The quotation that would have to be stored in the meta-data of the assembly would look like this:
let rec x = <@ (fun() -> %x + "abc") () @>
The body is quoted, but x
is not a quoted symbol, so it needs to be spliced into the quotation (that is, it will be evaluated and the result will be used in its place). Note that this code will fail, because you're declaring a recursive value with immediate reference - x
needs to be evaluated as part of its definition, so this won't work.
However, I think that %
cannot appear in ReflectedDefinition
quotations (that is, you cannot store the above in meta-data), because it involves some runtime aspects - you'd need to evaluate x
when loading the meta-data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With