Pattern with action for two statements - rascal

I'm am trying to match and delete two statements with rascals visit statement. Of course I would also need to check if they are used but in this case, I don't have to worry about that. In the example below, you can see two tmp variabels which are created but not used (this is semi-pseudo Rust code). They are only created as temporary variables and freed. (I have tried to create equivelant in Java but it lost some context in translation like for example the redeclaration of the tmp)
{
let tmp : c_void = repository as c_void;
repository = MArray();
free(tmp);
let tmp : c_void = where_ as c_void;
where_ = MArray();
free(tmp);
}
This is an example of the simplified version of the pattern with action which I have been playing with. With this pattern, I would think that the first free statement would be matched but it apparently is the last one within the scope. I have tried to do this in all kind of ways like statement counters and various different patterns to no success.
visit(crate){
case (Statements) `let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);` =>
(Statements) `<Statement* stmts>`
}
The final product should look like following:
{
repository = MArray();
where_ = MArray();
}
Edit: Progress
I have managed to do what I wanted with the following code (this is still just the semi-pseudo Rust):
crate = innermost visit(crate){
case (Statements) `let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);
'<Statement* post_stmts>` =>
(Statements) `<Statement* stmts>
'<Statement* post_stmts>`
case (Statements) `<Statement* pre_stmts>
'let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts>
'free(tmp);` =>
(Statements) `<Statement* pre_stmts>
'<Statement* stmts>`
}
This now works for a single scope matching of both tmp instances but it does not expand into other scopes. I'm not sure why it doesn't just continue to match in other scopes despite it using the innermost matching. An example of an if else would be fitting for this. It matches and changes the tmp instances in the if branch but it does not continue into the else branch to also match them there.
Edit: Final
This seems to be solved now. I was wondering if adding another case would help and yes it did. Apparentaly it was not the problem of not reaching the scope but a problem of not matching the contents of the scope. Here is the modified code which works (I had to change the statements names because Rascal complaining about redeclared Statement* names accros cases):
crate = innermost visit(crate){
case (Statements) `let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>` =>
(Statements) `<Statement* stmts1>
'<Statement* stmts2>`
case (Statements) `<Statement* stmts3>
'let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts4>
'free(tmp);` =>
(Statements) `<Statement* stmts3>
'<Statement* stmts4>`
case (Statements) `<Statement* stmts5>
'let mut tmp : *mut ::std::os::raw::c_void = <Identifier _> as (*mut ::std::os::raw::c_void);
'<Statement* stmts6>
'free(tmp);
'<Statement* stmts7>` =>
(Statements) `<Statement* stmts5>
'<Statement* stmts6>
'<Statement* stmts7>`
}
^ (This example is the actual code an not a semi-pseudo code anymore.)

There is no place holder after the last free(tmp); so the last free(tmp) has to match. May be use a pattern like this:
`let tmp : c_void = <Identifier _> as c_void;
'<Statement* stmts1>
'free(tmp);
'<Statement* stmts2>`
I don't know the precise details of your example, but you could give this a try.

Related

Does F# support 'call-by-name' semantics?

For a while F# has supported the ability to auto-quote using [<ReflectedDefinitionAttribute>]. Is there anything similar for laziness?
e.g.
member __.Quoted ([<ReflectedDefinitionAttribute>] quotation:Expr<'T>) = ...
member __.Thunked ([<LazyAttribute>] thunk:Lazy<'T>) = ...
I suppose I could use something like
member __.Quoted ([<ReflectedDefinitionAttribute>] quotation:Expr<'T>) =
Lazy (evaluate (<# fun () -> %quotation #>)) // evaluate using Unquote or similar
But wouldn't this be costly?
UPDATE:
I found a hack, it's not exactly what I would like but it give the correct behavior.
type Signal = Signal with
member __.Return x = x
member __.Delay (f:unit -> _) = f
let a = Signal { return randint }
let b = Signal { return randint }
let c = Signal { return a() + b() }
There is nothing like the ReflectedDefinition attribute for automatically turning things into delayed Lazy<'T> computations.
You are right that automatically quoting the argument achieves something like this. You could use the (very limited) LeafExpressionConverter.EvaluateQuotation to do this for some limited kinds of expressions, but as you note, this would be inefficient. The following is a proof of concept though (but you cannot call custom functions in the branches as this uses LINQ expressions):
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.RuntimeHelpers
type A =
static member If<'T>(c:bool,
[<ReflectedDefinition>] t:Expr<'T>,
[<ReflectedDefinition>] f:Expr<'T>) =
if c then LeafExpressionConverter.EvaluateQuotation t :?> 'T
else LeafExpressionConverter.EvaluateQuotation f :?> 'T
A.If(1 = 2, 0, 1)
In practice, I think a more reasonable approach is to just use the built-in Lazy<'T> values. F# has a (not widely known) lazy keyword that gives you a bit nicer syntax for creating those:
let iff c (t:Lazy<_>) (f:Lazy<_>) =
if c then t.Value else f.Value
iff (1 = 2)
(lazy (printfn "true"; 41))
(lazy (printfn "false"; 42))

Why is function argument lifetime different to the lifetime of a binding inside a function?

Gave VisualRust another try and to see how far they got, I wrote a few lines of code. And as usual, the code causes me to write a question on stackoverflow...
See first, read my question later:
fn make_counter( state : &mut u32 ) -> Box<Fn()->u32>
{
Box::new(move || {let ret = *state; *state = *state + 1; ret })
}
fn test_make_counter() {
let mut cnt : u32 = 0;
{
let counter = make_counter( & mut cnt );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
}
fn alt_make_counter ( init : u32 ) -> Box<Fn()->u32> {
let mut state = init;
Box::new(move || {let ret = state; state = state + 1; ret })
}
fn test_alt_make_counter() {
let counter = alt_make_counter( 0u32 );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
fn main() {
test_make_counter();
test_alt_make_counter();
}
The difference between make_counter() and alt_make_counter() is, that in one case, the state is a pointer to a mutable u32 passed to the function and in the other case, it is a mutable u32 defined inside the function. As the test_make_counter() function shows clearly, there is no way, that the closure lives longer than the variable cnt. Even if I removed the block inside test_make_counter() they would still have the identical lifetime. With the block, the counter will die before cnt. And yet, Rust complains:
src\main.rs(4,2): error : captured variable state does not outlive the enclosing closure
src\main.rs(3,1): warning : note: captured variable is valid for the anonymous lifetime #1 defined on the block at 3:0
If you look at the alt_make_counter() function now, the lifetime of state should basically cause the same error message, right? If the code captures the state for the closure, it should not matter if the pointer is passed in or if the variable is bound inside the function, right? But obviously, those 2 cases are magically different.
Who can explain, why they are different (bug, feature, deep insight, ...?) and if there is a simple rule one can adopt which prevents wasting time over such issues now and then?
The difference is not in using a local variable vs. using a parameter. Parameters are perfectly ordinary locals. In fact, this version of alt_make_counter works1:
fn alt_make_counter (mut state: u32) -> Box<FnMut() -> u32> {
Box::new(move || {let ret = state; state = state + 1; ret })
}
The problem is that the closure in make_counter closes over a &mut u32 instead of u32. It doesn't have its own state, it uses an integer somewhere else as its scratch space. And thus it needs to worry about the lifetime of that location. The function signature needs to communicate that the closure can only work while it can still use the reference that was passed in. This can be expressed with a lifetime parameter:
fn make_counter<'a>(state: &'a mut u32) -> Box<FnMut() -> u32 + 'a> {
Box::new(move || {let ret = *state; *state = *state + 1; ret })
}
Note that 'a is also attached to the FnMut() -> u32 (though with a different syntax because it's a trait).
The simplest rule to avoid such trouble is to not use references when they cause problems. There is no good reason for this closure to borrow its state, so don't do it. I don't know whether you fall under this, but I've seen a bunch of people that were under the impression that &mut is the primary or only way to mutate something. That is wrong. You can just store it by value and then just mutate that directly by storing it, or the larger structure in which it is contained, in a local variable that is tagged as mut. A mutable reference is only useful if the results of the mutation needs to be shared with some other code and you can't just pass the new value to that code.
Of course, sometimes juggling references in complicated ways is necessary. Unfortunately there doesn't seem to be a quick and easy way to learn to deal with those confidently. It's a big pedagogic challenge, but so far it appears everyone just struggled for a while and then progressively had fewer problems as they get more experienced. No, there is no single simple rule that solves all lifetime woes.
1 The return type has to be FnMut in all cases. You just didn't get an error about that yet because your current error happens at an earlier stage in the compilation.

Random / State workflow in F#

I'm trying to wrap my head around mon-, err, workflows in F# and while I think that I have a pretty solid understanding of the basic "Maybe" workflow, trying to implement a state workflow to generate random numbers has really got me stumped.
My non-completed attempt can be seen here:
let randomInt state =
let random = System.Random(state)
// Generate random number and a new state as well
random.Next(0,1000), random.Next()
type RandomWF (initState) =
member this.Bind(rnd,rest) =
let value, newState = rnd initState
// How to feed "newState" into "rest"??
value |> rest
member this.Return a = a // Should I maybe feed "initState" into the computation here?
RandomWF(0) {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c]
} |> printfn "%A"
Edit: Actually got it to work! Not exactly sure how it works though, so if anyone wants to lay it out in a good answer, it's still up for grabs. Here's my working code:
type RandomWF (initState) =
member this.Bind(rnd,rest) =
fun state ->
let value, nextState = rnd state
rest value nextState
member this.Return a = fun _ -> a
member this.Run x = x initState
There are two things that make it harder to see what your workflow is doing:
You're using a function type for the type of your monad,
Your workflow not only builds up the computation, it also runs it.
I think it's clearer to follow once you see how it would look without those two impediments. Here's the workflow defined using a DU wrapper type:
type Random<'a> =
Comp of (int -> 'a * int)
let run init (Comp f) = f init
type Random<'a> with
member this.Run(state) = fst <| run state this
type RandomBuilder() =
member this.Bind(Comp m, f: 'a -> Random<_>) =
Comp <| fun state ->
let value, nextState = m state
let comp = f value
run nextState comp
member this.Return(a) = Comp (fun s -> a, s)
let random = RandomBuilder()
And here is how you use it:
let randomInt =
Comp <| fun state ->
let rnd = System.Random(state)
rnd.Next(0,1000), rnd.Next()
let rand =
random {
let! a = randomInt
let! b = randomInt
let! c = randomInt
return [a; b; c ]
}
rand.Run(0)
|> printfn "%A"
In this version you separately build up the computation (and store it inside the Random type), and then you run it passing in the initial state. Look at how types on the builder methods are inferred and compare them to what MSDN documentation describes.
Edit: Constructing a builder object once and using the binding as an alias of sorts is mostly convention, but it's well justified in that it makes sense for the builders to be stateless. I can see why having parameterized builders seems like a useful feature, but I can't honestly imagine a convincing use case for it.
The key selling point of monads is the separation of definition and execution of a computation.
In your case - what you want to be able to do is to take a representation of your computation and be able to run it with some state - perhaps 0, perhaps 42. You don't need to know the initial state to define a computation that will use it. By passing in the state to the builder, you end up blurring the line between definition and execution, and this simply makes the workflow less useful.
Compare that with async workflow - when you write an async block, you don't make the code run asynchronously. You only create an Async<'a> object representing a computation that will produce an object of 'a when you run it - but how you do it, is up to you. The builder doesn't need to know.

Why does this point-free F# function behave differently from the non-point-free version?

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.

F# mutable function arguments

Is there a way to have mutable function arguments in F#, that would allow something like
let mutable i = 9
let somefun n = n <- 12; ()
somefun i
(* *not* a real-world example *)
I do understand that this can be made to work by wrapping it into a record type
type SomeRec = { mutable i: int }
let ri = { i = 9 }
let someotherfun r = r.i <- 12; ()
and that this can be done in a similar fashion for class members. However, even after browsing through the whole F# Language Specification (yes, I did!), there seems to be no syntax to allow the first case, and the compiler appears to be quite unhappy about my trying this. I was hoping there would be some sort of type annotation, but mutable cannot be used in such.
I also know that I should not be doing this sort of thing in the first place, but the first case (int binding) and the second (record type) are semantically identical, and any such objection would hold for both cases equally.
So I think that I am missing something here.
You can use ref as arguments
let v = ref 0
let mutate r =
r := 100
mutate v
printfn "%d" !v
Or byref keyword
let mutable v = 0
let mutate (r : byref<_>) =
r <- 100
mutate &v
printfn "%d" v
Use byref keyword which is equivalent to C# ref.
See Passing by reference.

Resources