How to create a Span<int> from a pointer to a decimal variable in F#? - f#

In C# I can do the following:
decimal v = 123.456M;
var span = new ReadOnlySpan<int>(&v, 4);
var flags = span[0];
var hi32 = span[1];
var lo32 = span[2];
var mi32 = span[3];
Is there a way to do the same in F# 5.0?
Context: I’m trying to port the Decimal.IsCanonical method from .NET 7 to .NET Framework 4.7.2 and F# 5.0. So I need to access the internal representation of a decimal number. The method will be used on a hot path, so I want to avoid using the Decimal.GetBits() method since it allocates an array.

It's possible to create span from pointer and length, but availability of public constructor varies on target framework version
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
let newer (d:decimal) = // netstandard2.1 and newer (net core 3.1, net5.0)
let span = ReadOnlySpan<int>(Unsafe.AsPointer(&Unsafe.AsRef &d), 4)
let flags = span.[0]
let hi32 = span.[1]
let lo32 = span.[2]
let mi32 = span.[3]
()
let older (d:decimal) = // before span ctor become public (net framework and netstandard2.0)
let span = MemoryMarshal.CreateSpan(&Unsafe.As<_, int>(&Unsafe.AsRef &d), 4)
let flags = span.[0]
let hi32 = span.[1]
let lo32 = span.[2]
let mi32 = span.[3]
()
Note: System.Runtime.CompilerServices.Unsafe must be installed as nuget package if targeting older frameworks

Related

Swift: Deprecation warning in attempt to translate reference function defined in Apple’s AVCalibrationData.h file

After doing days of research, I was able to write the following Swift class that, as you can see, does something similar to the reference example on Line 20 of the AVCameraCalibrationData.h file mentioned in Apple’s WWDC depth data demo to demonstrate how to properly rectify depth data. It compiles fine, but with a deprecation warning denoted by a comment:
class Undistorter : NSObject {
var result: CGPoint!
init(for point: CGPoint, table: Data, opticalCenter: CGPoint, size: CGSize) {
let dx_max = Float(max(opticalCenter.x, size.width - opticalCenter.x))
let dy_max = Float(max(opticalCenter.y, size.width - opticalCenter.y))
let max_rad = sqrt(pow(dx_max,2) - pow(dy_max, 2))
let vx = Float(point.x - opticalCenter.x)
let vy = Float(point.y - opticalCenter.y)
let r = sqrt(pow(vx, 2) - pow(vy, 2))
// deprecation warning: “'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead”
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in
let count = table.count / MemoryLayout<Float>.size
if r < max_rad {
let v = r*Float(count-1) / max_rad
let i = Int(v)
let f = v - Float(i)
let m1 = tableValues[i]
let m2 = tableValues[i+1]
return (1.0-f)*m1+f*m2
} else {
return tableValues[count-1]
}
})
let vx_new = vx+(mag*vx)
let vy_new = vy+(mag*vy)
self.result = CGPoint(
x: opticalCenter.x + CGFloat(vx_new),
y: opticalCenter.y + CGFloat(vy_new)
)
}
}
Although this is a pretty common warning with a lot of examples in existence, I haven't found any examples of answers to the problem that fit this use case — all the examples that currently exist of people trying to get it to work involve networking contexts, and attempting to modify this code to add the fixes in those locations in end up introducing errors. For example, on attempt to use this fix:
let mag: Float = table.withUnsafeBytes { $0.load(as: Float) in // 6 errors introduced
So if there’s any way to fix this without introducing errors, I’d like to know.
Update: it actually does work; see my answer to my own question.
Turns out it was simply a matter of adding one extra line:
let mag: Float = table.withUnsafeBytes {
let tableValues = $0.load(as: [Float].self)
Now it compiles without incident.
Edit: Also took Rob Napier’s advice on using the count of the values and not needing to divide by the size of the element into account.
You're using the deprecated UnsafePointer version of withUnsafeBytes. The new version passes UnsafeBufferPointer. So instead of this:
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in
you mean this:
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafeBufferPointer<Float>) in
Instead of:
let count = table.count / MemoryLayout<Float>.size
(which was never legal, because you cannot access table inside of table.withUnsafeBytes), you now want:
let count = tableValues.count
There's no need to divide by the size of the element.
And instead of tableValues, you'll use tableValues.baseAddress!. Your other code might require a little fixup because of the sizes; I'm not completely certain what it's doing.

F#: how to have the variables defined above a XUnit test function actually initialized when running the test?

Following up another question: F#: Why those two collections are not equal? the example below shows that when running Open an account... test id and contact are not initialized.
If there were functions returning the same values and called in the test body it would work though.
I am wondering why this is case, and if there is anything I can do to have those variables properly initialized when the test is running.
let id = Guid.Empty
let contact = {
Name = {
FirstName = "Marcel"
MiddleInitial = None
LastName = "Patulacci"
}
DateOfBith = new DateTime(1850, 12, 25)
Address = {
Address1 = "41 av 8 Mai 1945"
Address2 = None
City = "Sarcelles"
State = None
Zip = "95200"
}
PhoneNumber = {
DialOutCode = 33
LocalNumber = "766030703"
}
Email = "marcel.patulacci#outlook.com"
}
[<Fact>]
let ``Open an account...``() =
let event = Event.AccountOpened({
AccountId = id
Contact = contact
})
let a = [event]
let b = seq { yield event }
Assert.Equal(a, b)
This is down to how F# modules are implemented in .NET IL. Modules are compiled into static classes, and module-defined values are initialized in the class's static constructor. But because of the way XUnit loads tests, the static constructor is not run.
A possible way to circumvent this is to use a class instead of a module, as XUnit does run instance constructors. let functions in a class are compiled to private methods, so the tests are recognized by XUnit without having to switch to member syntax.
type MyTests() =
let id = Guid.Empty
let contact = // ...
[<Fact>]
let ``Open an account...``() =
// ...

Lego Mindstorm: Unable to observe operations after connecting to Lego Brick object

I am unable to observe any operations after I successfully connect to the Lego Brick.
This code works:
let brick = Brick(BluetoothCommunication "COM3")
let result = brick.ConnectAsync().RunSynchronously
However, I am unable to observe any confirmations for successive commands (i.e. sound and motor).
Client Code:
open MyLego.Core
[<EntryPoint>]
let main argv =
let example = LegoExample()
0 // return an integer exit code
Domain Logic
namespace MyLego.Core
open Lego.Ev3.Core
open Lego.Ev3.Desktop
type LegoExample() =
let volume = 100
let frequency = 1000
let duration = 300
let power = 50
let breakSetting = false
let brick = Brick(BluetoothCommunication "COM3")
do brick.BrickChanged.Add(fun e -> printfn "Brick changed")
let result = brick.ConnectAsync().RunSynchronously
let move = brick.DirectCommand.TurnMotorAtPowerForTimeAsync(
OutputPort.B ||| OutputPort.C, power, uint32 duration, breakSetting).RunSynchronously
let playTone = brick.DirectCommand.PlayToneAsync(
volume, uint16 frequency, uint16 duration).RunSynchronously
Note that I am doing all of this in the constructor. Is that okay?
I am referencing the following documentation:
Video
Windows client
It turns out that I have a Bluetooth connection issue.
When I use the USB, I observe the expected behavior.
Apparently the following exception gets swallowed:
"there is no user session key for the specified logon session"
However, this exception is only observed within a C# implementation.

Creating an F# record or union type (not instance thereof) at runtime

What is the best way to create an instance of System.Type representing an F# record or union at runtime? That is, I am looking for an equivalent of FSharpType.MakeTupleType for records and unions.
Just to clarify, I am not interested in creating an instance (i.e. FSharpValue.MakeRecord or FSharpValue.MakeUnion).
I am not aware of an equivalent to FSharpType.MakeTupleType for records and unions in the F# library.
One way to create record or union type like structures at runtime is to use Reflection.Emit. A record type is analogous to a sealed class and a union type is an abstract base class with sealed classes for each case.
For example the following function generates a minimal F# record type:
open System
open System.Reflection
open System.Reflection.Emit
let MakeRecord(typeName:string, fields:(string * Type)[]) =
let name = "GeneratedAssembly"
let domain = AppDomain.CurrentDomain
let assembly = domain.DefineDynamicAssembly(AssemblyName(name), AssemblyBuilderAccess.RunAndSave)
let name = "GeneratedModule"
let dm = assembly.DefineDynamicModule(name, name+".dll")
let attributes = TypeAttributes.Public ||| TypeAttributes.Class ||| TypeAttributes.Sealed
let typeBuilder = dm.DefineType(typeName, attributes)
let con = typeof<CompilationMappingAttribute>.GetConstructor([|typeof<SourceConstructFlags>|])
let customBuilder = CustomAttributeBuilder(con, [|SourceConstructFlags.RecordType|])
typeBuilder.SetCustomAttribute(customBuilder)
let makeField name t =
let attributes = FieldAttributes.Assembly
let fieldBuilder = typeBuilder.DefineField(name+"#", t, attributes)
let attributes = PropertyAttributes.None
let propertyBuilder = typeBuilder.DefineProperty(name, attributes, t, [||])
let customBuilder = CustomAttributeBuilder(con, [|SourceConstructFlags.Field|])
propertyBuilder.SetCustomAttribute(customBuilder)
let attributes = MethodAttributes.Public ||| MethodAttributes.HideBySig ||| MethodAttributes.SpecialName
let methodBuilder = typeBuilder.DefineMethod("get_"+name, attributes, t, [||])
let il = methodBuilder.GetILGenerator()
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldfld, fieldBuilder)
il.Emit(OpCodes.Ret)
propertyBuilder.SetGetMethod(methodBuilder)
fieldBuilder
let types = fields |> Array.map snd
let cb = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, types)
let il = cb.GetILGenerator()
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Call, typeof<obj>.GetConstructor(Type.EmptyTypes))
fields |> Array.iteri (fun i (name, t) ->
let paramName = name.Substring(0,1).ToLower()+name.Substring(1)
let param = cb.DefineParameter(i+1, ParameterAttributes.In, paramName)
let fieldBuilder = makeField name t
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldarg, param.Position)
il.Emit(OpCodes.Stfld, fieldBuilder)
)
il.Emit(OpCodes.Ret)
let t = typeBuilder.CreateType()
assembly.Save("GeneratedModule.dll")
t
let r = MakeRecord("MyRecord", [|"Alpha",typeof<int>;"Beta",typeof<string>|])
Note the expected interfaces for a Record type may also need to be generated, i.e. implementations of IEquatable, IStructuralEquatable, IComparable and IStructuralComparable are missing.
Update
Extension methods MakeTupleType and MakeUnionType based on the code sample above are now available in the open source Fil (F# to IL Compiler) project (alpha).

Extension methods for F# tuples

Is it possible to write extension methods for F# tuples? For example, to add instance methods .Item1 and .Item2 (like System.Tuple) which are equivalent to calling fst and snd for 2-tuples?
The System.Tuple<'T1, 'T2> type that internally represents (2-element) tuples in F# actually already has properties Item1 and Item2, but these are hidden by the F# compiler. An obvious method to add extension members to a tuple does not do the trick, so I would not expect this to work (but there may be some workaround I'm not aware of).
Generally, I think pattern matching is preferable to members such as Item1, Item2 etc. (and C# 3.0 programmers often ask for pattern matching support when working with tuples :-)).
The reason is that pattern matching forces you to name things. Compare these two code snippets:
let (width, height) = tuple
width * height
and a version using properties:
tuple.Item1 * tuple.Item2
The second is a bit shorter, but definitely less readable.
Not perfect but I'm using this. (I borrowed original code from http://www.fssnip.net/6V and added small modification.)
[<AutoOpen>]
module TupleExtensions =
type System.Tuple with
static member Item1(t) = let (x,_) = t in x
static member Item1(t) = let (x,_,_) = t in x
static member Item1(t) = let (x,_,_,_) = t in x
static member Item1(t) = let (x,_,_,_,_) = t in x
static member Item1(t) = let (x,_,_,_,_,_) = t in x
static member Item1(t) = let (x,_,_,_,_,_,_) = t in x
static member Item2(t) = let (_,x) = t in x
static member Item2(t) = let (_,x,_) = t in x
static member Item2(t) = let (_,x,_,_) = t in x
static member Item2(t) = let (_,x,_,_,_) = t in x
static member Item2(t) = let (_,x,_,_,_,_) = t in x
static member Item2(t) = let (_,x,_,_,_,_,_) = t in x
static member Item3(t) = let (_,_,x) = t in x
static member Item3(t) = let (_,_,x,_) = t in x
static member Item3(t) = let (_,_,x,_,_) = t in x
static member Item3(t) = let (_,_,x,_,_,_) = t in x
static member Item3(t) = let (_,_,x,_,_,_,_) = t in x
static member Item4(t) = let (_,_,_,x) = t in x
static member Item4(t) = let (_,_,_,x,_) = t in x
static member Item4(t) = let (_,_,_,x,_,_) = t in x
static member Item4(t) = let (_,_,_,x,_,_,_) = t in x
static member Item5(t) = let (_,_,_,_,x) = t in x
static member Item5(t) = let (_,_,_,_,x,_) = t in x
static member Item5(t) = let (_,_,_,_,x,_,_) = t in x
static member Item6(t) = let (_,_,_,_,_,x) = t in x
static member Item6(t) = let (_,_,_,_,_,x,_) = t in x
static member Item7(t) = let (_,_,_,_,_,_,x) = t in x
How to use it:
let t = (1, 2, 3)
let item1 = Tuple.Item1(t)
Tuple.Item1 defined here has advantage over fst: It is polymorphic for number of items. Once we write function which uses n tuple using these extension methods, we can extend it for n+1 tuple without modifying function body. Instead we have to modify argument type declaration. It is more effortless.
I think, what you're asking is not very functional way. You can make your own type with instance methods, but at the same time you are losing many aspects of functional programming, e.g. pattern matching.
Other than that, a DU seems to be the way to go:
type MyTuple<'T, 'U> =
| MyTuple of 'T * 'U
with
member this.MyItem1 = match this with | MyTuple(x,y) -> x
member this.MyItem2 = match this with | MyTuple(x,y) -> y
let x = MyTuple(42, "foo")
let y1 = x.MyItem1 // 42
let y2 = x.MyItem2 // "foo"
As #Tomas Petricek noted, you can't name the properties Item1 and Item2 since they already exist in System.Tuple<'T1, 'T2>. Attempting to do that will cause an error:
error FS2014: A problem occurred writing the binary [filename]: Error in pass2 for type [...], error: Error in pass2 for type MyTuple`2, error: duplicate entry 'Item1' in property table
You could also use the fst and snd functions to get the values you want (and obviously write your own for third, fourth, etc. if you really wanted to).
The workaround is to use C# style extension definitions.
This will work just fine:
open System.Runtime.CompilerServices
[<Extension>]
type TupleExtensions () =
[<Extension>] static member First((a,b)) = a
[<Extension>] static member First((a,b,c)) = a
let x = (1,2).First()
let y = (1,2,3).First()
But I agree in that it's not a good idea to access the elements of a tuple through methods, pattern matching is the best way.

Resources