I understand that they're different since one works for setting *compile-path* and one doesn't. However, I need help with why they're different.
let creates a new scope with the given bindings, but binding...?
let creates a lexically scoped immutable alias for some value. binding creates a dynamically scoped binding for some Var.
Dynamic binding means that the code inside your binding form and any code which that code calls (even if not in the local lexical scope) will see the new binding.
Given:
user> (def ^:dynamic x 0)
#'user/x
binding actually creates a dynamic binding for a Var but let only shadows the var with a local alias:
user> (binding [x 1] (var-get #'x))
1
user> (let [x 1] (var-get #'x))
0
binding can use qualified names (since it operates on Vars) and let can't:
user> (binding [user/x 1] (var-get #'x))
1
user> (let [user/x 1] (var-get #'x))
; Evaluation aborted.
;; Can't let qualified name: user/x
let-introduced bindings are not mutable. binding-introduced bindings are thread-locally mutable:
user> (binding [x 1] (set! x 2) x)
2
user> (let [x 1] (set! x 2) x)
; Evaluation aborted.
;; Invalid assignment target
Lexical vs. dynamic binding:
user> (defn foo [] (println x))
#'user/foo
user> (binding [x 1] (foo))
1
nil
user> (let [x 1] (foo))
0
nil
See also Vars, let.
One more syntactic difference for let vs binding:
For binding, all the initial values are evaluated before any of them are bound to the vars. This is different from let, where you can use the value of a previous "alias" in a subsequent definition.
user=>(let [x 1 y (+ x 1)] (println y))
2
nil
user=>(def y 0)
user=>(binding [x 1 y (+ x 1)] (println y))
1
nil
binding binds a value to a name in the per-thread global environment
As you mentioned, let creates a new scope for said bindings.
Related
Note the following Z3-Py code:
x, y = Ints('x y')
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
s = Solver()
phi = Exists([y],ForAll([x], Implies(negS0, And(s1,s2))))
s.add(phi)
print(s.check())
print(s.model())
This prints:
sat
[]
My question is: why is the model empty? I mean, I think y=2 should be a model...
Note that the same result happens with x and y being Real.
z3 will not include any quantified variable (in your case neither y nor x) in its model. Note that you cannot put x in a model anyhow, because the formula is true for all x: That's the meaning of universal quantification. For the outer-most existentials (like your y), z3 can indeed print the model value for that, but it chooses not to do so since it can be confusing: Imagine you had a phi2, which also had an outer-most existential named y: How would you know which y it would be that it prints in the model?
So, z3 keeps things simple and simply prints the top-level declared variables in the model. And since a top-level declaration is equivalent to an outermost existential, you can simply drop it:
from z3 import *
x, y = Ints('x y')
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
s = Solver()
phi = ForAll([x], Implies(negS0, And(s1,s2)))
s.add(phi)
print(s.check())
print(s.model())
This prints:
sat
[y = 2]
like you predicted. Note that this y is unambiguous, since it's declared at the top-level. (Of course, you can redefine it to be something else due to the loosely typed nature of Python bindings and still get yourself confused, but that's a different discussion.)
in F#, it's not allowed to have mutable argument with functions. but if I have a function like the following:
let f x =
while x>0 do
printfn "%d" x
x <- x-1;;
when I compile this, I'm getting a compiler error.(not mutable)
How would I fix this function?
For pass-by-value semantics, you can use parameter shadowing.
Here, a shadowed (because it's the same name) mutable value x is declared on the stack.
let f x =
let mutable x = x
while x > 0 do
printfn "%d" x
x <- x - 1
For pass-by-reference semantics, you'll have to use a reference cell, which is a just a fancy way of passing an object which has a mutable field in it. It's similar to ref in C#:
let f x =
while !x > 0 do
printfn "%d" !x
x := !x - 1
Using a reference cell:
let x = (ref 10)
f x
Debug.Assert(!x = 0)
You could rewrite it like this:
let f x = [x.. -1..1] |> List.iter (printfn "%d")
If you want to keep the while loop, you could do this:
let f (x : byref<int>)=
while x>0 do
printfn "%d" x
x <- x-1
let mutable x = 5
f &x
Depends on whether you want the final, mutated value of x to be passed back to the caller of the function or mutate it only locally.
For local-only mutation, just declare another variable, which would be mutable, but initially will have the value of x:
let f x =
let mutable i = x
while i>0 do
printfn "%d" i
i <- i-1
For passing the result back to the caller, you can use a ref-cell:
let f (x: int ref) =
while x.Value>0 do
printfn "%d" x.Value
x := x.Value - 1
Note that now you have to refer to the ref-cell contents via the .Value property (or you can instead use operator !, as in x := !x - 1), and the mutation is now done via :=. Plus, the consumer of such function now has to create a ref-cell before passing it in:
let x = ref 5
f x
printfn "%d" x.Value // prints "0"
Having said that, I must point out that mutation is generally less reliable, more error-prone than pure values. The normal way to write "loops" in pure functional programming is via recursion:
let rec f x =
if x > 0 then
printf "%d" x
f (x-1)
Here, each call to f makes another call to f with the value of x decreased by 1. This will have the same effect as the loop, but now there is no mutation, which means easier debugging and testing.
I need help reversing bits in F# as done in this question Reverse bits in number. I'm new to F# and was wondering how we can do this?
let bitreverse x =
let mutable b = 0
while x do
b >>>= 1
b|= x & 1
x >>>= 1
b
I'm not even sure the syntax is correct here. I am very knew to this language.
The direct translation into F# looks like this:
let bitreverse x =
let mutable x = x
let mutable b = 0
while x <> 0 do
b <- b <<< 1
b <- b ||| (x &&& 1)
x <- x >>> 1
b
This is highly imperative with mutable values and this isn't usually how we'd tend to go about writing code in F#. Notice that re-assignment of a mutable variable is a little different to what you might be used to in an imperative language, you have to use <- which is called the destructive update operator.
Thankfully, it's pretty straightforward to translate this into a recursive function that uses immutable values which should be a little more idiomatic
let bitreverse2 x =
let rec bitRerverseHelper b x =
match x with
|0 -> b // if 0, the recursion stops here and we return the result: b
|_ -> bitRerverseHelper ((b <<< 1) ||| (x &&& 1)) (x >>> 1) // otherwise recurse
bitRerverseHelper 0 x
F# doesn't support compound assignment, so you can't do something like b |= x & 1, you need to expand it to b <- b ||| (x &&& 1).
The argument x isn't mutable, so you need to create a local binding and mutate that. It looks weird, but you can just write let mutable x = x as the first line of your function to shadow the existing binding with a mutable one.
x is an int, not a bool, so you can't use it as the condition for your while loop. Use x <> 0 instead.
Indentation matters in F#, so make sure that while and your final b both line up with the first let.
Fixing those issues will make your code work, but idiomatic F# would probably forgo the while loop and mutation and use a recursive inner function with an accumulator instead.
I'm using quotations in F# to build a function which checks whether a single input satisfies any of a number of cases. That is, a function whos body is something like ... || ... || ..., where the number of ||s is determined at runtime. Somewhat simplified, what I have now is
let vals = [|1..3|]
let currentfilter =
vals
|> Array.fold (fun acc i ->
<# fun j -> (%acc) j || j = i #>)
<# fun _ -> false #>
which generates the tree
val currentfilter : Expr<(int -> bool)> =
Lambda (j,
IfThenElse (Application (Lambda (j,
IfThenElse (Application (Lambda (j,
IfThenElse (Application (Lambda (_arg1,
Value (false)),
j),
Value (true),
Call (None,
op_Equality,
[j,
Value (1)]))),
j),
Value (true),
Call (None, op_Equality,
[j, Value (2)]))), j),
Value (true), Call (None, op_Equality, [j, Value (3)])))
Optimally, what I want to generate is more like
Lambda (j,
IfThenElse (IfThenElse (Call (None, op_Equality, [j, Value (1)]),
Value (true),
Call (None, op_Equality, [j, Value (2)])),
Value (true), Call (None, op_Equality, [j, Value (3)])))
(This was generated by <# fun j -> j = 1 || j = 2 || j = 3 #>)
Is there any easy way of flattening the first expression, in order to make it look more like the second?
You can write the code so that it does not return quoted function but instead returns a function that generates quotation when given the input:
let vals = [|1..3|]
let currentfilter =
vals |> Array.fold (fun acc i ->
fun j -> <# %(acc j) || %j = i #>)
(fun _ -> <# false #>)
In the fold:
Initial value is a function that returns false expression
Aggregation composes the expression generated so far with an expression that compares the input (specified as a quotation) with the value i.
Now, to create the complete quoted function, we would like to write something like this:
<# fun j -> %(currentfilter <# j #>) #>
Sadly, this does not work - because the F# compiler is a bit strict here and does not let us write code where the variable j could escape its scope (quite reasonable, but unfortunate).
So, instead, you can write this by constructing the quotation manually:
open Microsoft.FSharp.Quotations
let v = Var.Global("j", typeof<int>)
Expr.Lambda(v, currentfilter (Expr.Cast(Expr.Var(v))))
I have this bit of code:
let rec h n z = if n = 0 then z
else <# (fun x -> %(h (n - 1) <# x + %z #>)) n #>
converted from a MetaOcaml example in http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf
In the paper there is explained that the above example will yield the following with the parameters 3 and .<1>. (in MetaOcaml notation):
.<(fun x_1 -> (fun x_2 -> (fun x_3 -> x_3 + (x_2 + (x_1 + 1))) 1) 2) 3>.
As you can see the x´s gets replaced by x_1, x_2 etc. because the x would otherwise only refer to the x in the innermost fun.
But in F# this isn't allowed. I get the compile-time error: "The variable 'x' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope." So the question is: how can this be changed so it will compile and have the same semantic as the MetaOcaml output?
Update to comment: I use the PowerPack to actually evaluating the quotation. But I don't think this have anything to do with it because the error is at compile-time. So far QuotationEvaluation works. However, I do know it may not be the most efficient implementation.
Update to Tomas´ answer:
I really don't want the x to be global, or to escape scope. But I want is the equivalent to
let rec h n z = if n = 0 then z
else (fun x -> (h (n - 1) (x + z))) n
with quotations. Your answer gives (h 3 <# 1 #>).Eval() = 4 where the above yields h 3 1 = 7. And here, I want 7 to be the answer.
F# quotation syntax doesn't support variables that could potentially escape the scope, so you'll need to construct the tree explicitly using the Expr operations. Something like this should do the trick:
open Microsoft.FSharp.Quotations
let rec h n (z:Expr<int>) =
if n = 0 then z
else
let v = new Var("x", typeof<int>)
let ve = Expr.Var(v)
Expr.Cast<int>
(Expr.Application( Expr.Lambda(v, h (n - 1) <# %%ve + %z #>),
Expr.Value(n)))
However, this is quite artificial example (to demonstrate variable capturing in MetaOCaml, which isn't available in F#). It just generates expression like (2 + (1 + ...)). You can get the same result by writing something like this:
let rec h n (z:Expr<int>) =
if n = 0 then z
else h (n - 1) <# n + %z #>
Or even better:
[ 1 .. 4 ] |> List.fold (fun st n -> <# n + %st #>) <# 0 #>
I also came accross this limitation in F# quotations and it would be nice if this was supported. However, I don't think it is such a big problem in practice, because F# quotations are not used for staged meta-programming. They are more useful for analyzing existing F# code than for generating code.