Creating anonymous record types at run-time - reflection

F# provides reflection that let's you, amongst other things, generate new values of function, tuple, record and union types at run-time. However, I cannot see anything in that module pertaining to anonymous records.
Is it possible to create new values of anonymous record types at run-time in F#?

The FSharp.Reflection.FSharpValue.MakeRecord method works for anonymous records just as well as for nominal ones:
let x = {| a = "b"; c = 42 |}
ley y = FSharp.Reflection.FSharpValue.MakeRecord( x.GetType(), [| "foo"; 5 |] )
> val it : obj = {a = "foo"; c = 5;}
Or did I misunderstand the question?

Related

F# Memoization - Persist?

What's the best way to persist/save the results of memoization so it can be loaded later?
There's this standard code snippet in F# for implementing memoization:
let memoize f =
let dict = Dictionary<_, _>();
fun c ->
let exist, value = dict.TryGetValue c
match exist with
| true -> value
| _ ->
let value = f c
dict.Add(c, value)
value
let mySlowFunc x=
// something very slow
0
let myFastFunc = memoize mySlowFunc
After calling myFastFunc many times, I will have a dictionary full of results for mySlowFunc for various x's. I want to persist these results so ideally I can do something like:
let saveMemoziationResults myFastFunc "results.file" = ... // saves the dict to a file
let loadMemoziationResults "results.file" // loads the dict from a file
I can't figure out a way to "access" that dict in order to save it.
You could move dict creation to the caller, like
let memoizeBase dict =
let memoize f = …
memoize
And using it like
let dict = new…
let memoize = memoizeBase dict
// use memoize and save/load dict when needed

Moq: How to mock a function in F# without a placeholder interface?

A colleague of mine needed to test whether some F# functions are called or not a given number of times.
In Moq, you can usually do that if you have a class with virtual members or an interface (unless if this has changed, but it doesn't seem to be the case), but afaik you can hardly mock static methods with Moq for example, which in most cases is how F# functions are compiled to, at least from an IL standpoint. Or, would require to use another library to do so like AutoFake or Pose and I'm not sure the F# support is actually properly implemented.
We ended up creating a CallCounter type, which would hold the function to invoke and a variable counting the number of times this function has been invoked (a bit similar to this answer but with an actual type).
module Tests
open Foq
open Xunit
open Swensen.Unquote
type CallCounter<'Input, 'Output>(f: 'Input -> 'Output) =
let mutable count = 0
member this.Count = count
member this.Invoke(input) =
count <- count + 1
f input
type CallOutputs<'Input, 'Output>(f: 'Input -> 'Output) =
let outputs = ResizeArray()
member this.Outputs =
List.ofSeq outputs
member this.Invoke(input) =
let output = f input
outputs.Add(output)
output
let callFunDepTwice (funDep: unit -> int32) =
sprintf "%A|%A" (funDep()) (funDep())
[<Fact>]
let ``callFunDepTwice should work1``() =
let funDep = fun() -> 42
let funDepCounter = CallCounter(funDep)
let actual = callFunDepTwice funDepCounter.Invoke
test <# actual = sprintf "%A|%A" 42 42 #>
test <# funDepCounter.Count = 2 #>
I was wondering if there was something out of the box in Moq to achieve the same sort of thing?
I mean without having to rely on creating a placeholder interface with an impl. using object expressions just for the grand sake to hold the function to invoke, in order to make it compliant with Moq, like below:
type ISurrogate<'Input, 'Output> =
abstract member Invoke: 'Input -> 'Output
[<Fact>]
let ``callFunDepTwice should work2``() =
let mockConf = Mock<ISurrogate<unit, int32>>().Setup(fun x -> <# x.Invoke() #>).Returns(42)
let mock = mockConf.Create()
let actual = callFunDepTwice mock.Invoke
test <# actual = sprintf "%A|%A" 42 42 #>
Mock.Verify(<# mock.Invoke() #>, Times.exactly 2)
Unless I'm missing something, I don't see why you need any objects or interfaces. Since it's all just functions, you could make funDep just increment a locally declared mutable counter as a side effect:
[<Fact>] let ``callFunDepTwice should work1``() =
let mutable count = 0
let funDep = fun() -> count <- count + 1; 42
let actual = callFunDepTwice funDep
test <# actual = sprintf "%A|%A" 42 42 #>
test <# count = 2 #>
Mocking frameworks may be occasionally useful in F# in some corner cases, but in general, I see their whole purpose as compensating for the deficiencies of OOP. Unless you're interacting with some .NET library that uses objects and interfaces, chances are you can do without them.

OCaml Self-Referential Map

I'm looking to add a cache to a simple compiler in OCaml. I have created a simpler version of the code that I had that reproduces the same issue. What I need for the cache is to be able to create a Map with A's as keys, so I can lookup the compile output. Here is the code:
module A
= struct
type ineq =
| LT
| EQ
| GT
type t =
...
module ACacheMapKey
= struct
type t = t
let compare a b =
match cmp a b with
| LT -> -1
| EQ -> 0
| GT -> 1
end
module CMap = Map.Make(ACacheMapKey)
let cache_map = CMap.empty
let cmp a b =
...
end
In module A, type t is a recursive AST-like type. cmp a b returns a ineq. The compile function was left out for brevity, but it just uses the cache before running through a computationally expensive process. In order to create a cache map in A, I need a compatible key module. My attempt at that is ACacheMapKey, but the type t = t doesn't refer to the parent. The error it gives is Error: The type abbreviation t is cyclic. So, is there a better way to make a cache over A? Or is there an easy way to reference the parent and make my current structure work?
Type definitions, unlike let bindings, are recursive by default. So similarly to how you would make a let binding recursive by using the rec keyword:
let rec f = ...
you can make a type definition non-recursive by using the nonrec keyword:
type nonrec t = t

Balanced tree for functional symbol table

I'm doing exercises of "Modern Compiler Implementation in ML" (Andrew Appel). One of which (ex 1.1 d) is to recommend a balanced-tree data structure for functional symbol table. Appeal mentioned such data structure should rebalance on insertion but not on lookup. Being totally new to functional programming, I found this confusing. What is key insight on this requirement?
A tree that’s rebalanced on every insertion and deletion doesn’t need to rebalance on lookup, because lookup doesn’t modify the structure. If it was balanced before a lookup, it will stay balanced during and after.
In functional languages, insertion and rebalancing can be more expensive than in a procedural one. Because you can’t alter any node in place, you replace a node by creating a new node, then replacing its parent with a new node whose children are the new daughter and the unaltered older daughter, and then replace the grandparent node with one whose children are the new parent and her older sister, and so on up. You finish when you create a new root node for the updated tree and garbage-collect all the nodes you replaced. However, some tree structures have the desirable property that they need to replace no more than O(log N) nodes of the tree on an insertion and can re-use the rest. This means that the rotation of a red-black tree (for example) has not much more overhead than an unbalanced insertion.
Also, you will typically need to query a symbol table much more often than you update it. It therefore becomes less tempting to try to make insertion faster: if you’re inserting, you might as well rebalance.
The question of which self-balancing tree structure is best for a functional language has been asked here, more than once.
Since Davislor already answered your question extensively, here are mostly some implementation hints. I would add that choice of data structure for your symbol table is probably not relevant for a toy compiler. Compilation time only starts to become an issue when you compiler is used on a lot of code and the code is recompiled often.
Sticking to a O(n) insert/lookup data structure is fine in practice until it isn't.
Signature-wise, all you want is a key-value mapping, insert, and lookup:
signature SymTab =
sig
type id
type value
type symtab
val empty : symtab
val insert : id -> value -> symtab -> symtab
val lookup : id -> symtab -> value option
end
A simple O(n) implementation with lists might be:
structure ListSymTab : SymTab =
struct
type id = string
type value = int
type symtab = (id * value) list
val empty = []
fun insert id value [] = [(id, value)]
| insert id value ((id',value')::symtab) =
if id = id'
then (id,value)::symtab
else (id',value')::insert id value symtab
fun lookup _ [] = NONE
| lookup id ((id',value)::symtab) =
if id = id' then SOME value else lookup id symtab
end
You might use it like:
- ListSymTab.lookup "hello" (ListSymTab.insert "hello" 42 ListSymTab.empty);
> val it = SOME 42 : int option
Then again, maybe your symbol table doesn't map strings to integers, or you may have one symbol table for variables and one for functions.
You could parameterise the id/value types using a functor:
functor ListSymTabFn (X : sig
eqtype id
type value
end) : SymTab =
struct
type id = X.id
type value = X.value
(* The rest is the same as ListSymTab. *)
end
And you might use it like:
- structure ListSymTab = ListSymTabFn(struct type id = string type value = int end);
- ListSymTab.lookup "world" (ListSymTab.insert "hello" 42 ListSymTab.empty);
> val it = NONE : int option
All you need for a list-based symbol table is that the identifiers/symbols can be compared for equality. For your balanced-tree symbol table, you need identifiers/symbols to be orderable.
Instead of implementing balanced trees from scratch, look e.g. at SML/NJ's RedBlackMapFn:
To create a structure implementing maps (dictionaries) over a type T [...]:
structure MapT = RedBlackMapFn (struct
type ord_key = T
val compare = compareT
end)
Try this example with T as string and compare as String.compare:
$ sml
Standard ML of New Jersey v110.76 [built: Sun Jun 29 03:29:51 2014]
- structure MapS = RedBlackMapFn (struct
type ord_key = string
val compare = String.compare
end);
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-LIB/Util/smlnj-lib.cm is stable]
[autoloading done]
structure MapS : ORD_MAP?
- open MapS;
...
Opening the structure is an easy way to explore the available functions and their types.
We can then create a similar functor to ListSymTabFn, but one that takes an additional compare function:
functor RedBlackSymTabFn (X : sig
type id
type value
val compare : id * id -> order
end) : SymTab =
struct
type id = X.id
type value = X.value
structure SymTabX = RedBlackMapFn (struct
type ord_key = X.id
val compare = X.compare
end)
(* The 'a map type inside SymTabX maps X.id to anything. *)
(* We are, however, only interested in mapping to values. *)
type symtab = value SymTabX.map
(* Use other stuff in SymTabT for empty, insert, lookup. *)
end
Finally, you can use this as your symbol table:
structure SymTab = RedBlackSymTabFn(struct
type id = string
type value = int
val compare = String.compare
end);

Type extension errors for Dictionary<'K, 'V>

The following type extension
module Dict =
open System.Collections.Generic
type Dictionary<'K, 'V> with
member this.Difference(that:Dictionary<'K, 'T>) =
let dict = Dictionary()
for KeyValue(k, v) in this do
if not (that.ContainsKey(k)) then
dict.Add(k, v)
dict
gives the error:
The signature and implementation are not compatible because the declaration of the type parameter 'TKey' requires a constraint of the form 'TKey : equality
But when I add the constraint it gives the error:
The declared type parameters for this type extension do not match the declared type parameters on the original type 'Dictionary<,>'
This is especially mysterious because the following type extension doesn't have the constraint and works.
type Dictionary<'K, 'V> with
member this.TryGet(key) =
match this.TryGetValue(key) with
| true, v -> Some v
| _ -> None
Now I'm having weird thoughts: is the constraint required only when certain members are accessed?
module Dict =
open System.Collections.Generic
type Dictionary<'K, 'V> with
member this.Difference(that:Dictionary<'K, 'T>) =
let dict = Dictionary(this.Comparer)
for KeyValue(k, v) in this do
if not (that.ContainsKey(k)) then
dict.Add(k, v)
dict
EDIT:
As per F# spec (14.11 Additional Constraints on CLI Methods)
Some specific CLI methods and types are treated specially by F#, because they are common in F# programming and cause extremely difficult-to-find bugs. For each use of the following constructs, the F# compiler imposes additional ad hoc constraints:
x.Equals(yobj) requires type ty : equality for the static type of x
x.GetHashCode() requires type ty : equality for the static type of x
new Dictionary<A,B>() requires A : equality, for any overload that does not take an IEqualityComparer<T>
as far as I can see the following code does the trick:
module Dict =
open System.Collections.Generic
type Dictionary<'K, 'V> with
member this.Difference(that: Dictionary<'K,'V2>) =
let diff =
this
|> Seq.filter (fun x -> not <| that.ContainsKey(x.Key))
|> Seq.map (fun x -> x.Key, x.Value)
System.Linq.Enumerable.ToDictionary(diff, fst, snd)
The problem is your use of the Add method. If you use this method of Dictionary<TKey, TValue> then F# will enforce that TKey has the equality constraint.
After playing around a bit I'm not sure that it's even possible to write this extension method. The F# type system appears to force the declaration type of the extension method to have no additional constraints than the original type (i get an error whenever I add the equality constraint). Additionally the type listed in the individal extension methods cannot differ than the listed type. I've tried a number of ways and can't get this to function correctly.
The closest I've come is the non-extension method as follows
let Difference (this : Dictionary<'K, 'T>) (that:Dictionary<'K, 'T> when 'K : equality) =
let dict = Dictionary()
for KeyValue(k, v) in this do
if not (that.ContainsKey(k)) then
dict.Add(k, v)
dict
Perhaps another F# ninja will be able to prove me wrong
(EDIT: CKoenig has a nice answer.)
Hm, I didn't immediately see a way to do this either.
Here's a non-type-safe solution that might provide some crazy inspiration for others.
open System.Collections.Generic
module Dict =
type Dictionary<'K, 'V> with
member this.Difference<'K2, 'T when 'K2 : equality>(that:Dictionary<'K2, 'T>) =
let dict = Dictionary<'K2,'V>()
for KeyValue(k, v) in this do
if not (that.ContainsKey(k |> box |> unbox)) then
dict.Add(k |> box |> unbox, v)
dict
open Dict
let d1 = Dictionary()
d1.Add(1, "foo")
d1.Add(2, "bar")
let d2 = Dictionary()
d2.Add(1, "cheese")
let show (d:Dictionary<_,_>) =
for (KeyValue(k,v)) in d do
printfn "%A: %A" k v
d1.Difference(d2) |> show
let d3 = Dictionary()
d3.Add(1, 42)
d1.Difference(d3) |> show
let d4 = Dictionary()
d4.Add("uh-oh", 42)
d1.Difference(d4) |> show // blows up at runtime
Overall it seems like there may be no way to unify the types K and K2 without also forcing them to have the same equality constraint though...
(EDIT: seems like calling into .NET which is equality-constraint-agnostic is a good way to create a dictionary in the absence of the extra constraint.)

Resources