Mappings and usage of Kotlin data types and Swift data types - ios

Let's say I have a function foo which takes two arguments:
actual fun foo(list1: List<Long>, list2: List<Double>) {
...
}
According to the https://kotlinlang.org/docs/tutorials/native/apple-framework.html Kotlin's Long type is mapped to KotlinLong and Kotlin's Double is mapped to KotlinDouble. Now I would like to call this function from my iOS App. Let's say I have two arrays:
let list1Numbers = [1000.43, 564121.34, 5617172172.234, 100.7]
let list2Numbers = [2.1, 3.2, 1.7]
For the list2 I could do something like:
let list2NumbersKotlin = list2Numbers.map({KotlinDouble.init(double: $0)})
which is not very convenient but will work. The list1 is a bit more problematic. Since there is no Long in Swift, I do something like
let list1NumbersKotlin = list1Numbers.map({KotlinLong.init(longLong: Int64($0))})
Questions:
Is there a better way to do it ?
What is a typical approach to deal with such types mapping when using Kotlin as an iOS Framework ? Unfortunately I couldn't find any examples on the Internet.
Should certain types such as Long be completely avoided if I want to use Kotlin as iOS Framework ?
Also, regarding mapping in general: since the Kotlin function
fun testDouble(testVal: Double) {}
allows me to pass in Swift the Double directly:
HelloKt.testDouble(testVal: Double)
then why does the function
fun testList(testList: List<Double>) {}
not allow me to enter Double array but requires a KotlinDouble array ?
HelloKt.testList(testList: [KotlinDouble]){}
Passing a [Double] gives error:
Cannot convert value of type '[Double]' to expected argument type
'[KotlinDouble]'

There are multiple ways.
You are talking about collections of data that are on the line between primitive types and objects, which tends to be a special case in Kotlin anyway.
Speaking to that, in Kotlin, you might want a LongArray and a DoubleArray rather than List<Long> and List<Double>. Coming from Swift, you'll be forced to explicitly box them. Kotlin will handle that for you when you're writing Kotlin code, but they're still getting boxed under the hood.
So, summary, either what you've done above, or take LongArray and DoubleArray as args rather than lists, and do a different translation. Either way, you will need to move the data into something Koltin compatible.
Obviously, if you put that in a helper function, ugly as it perhaps may be, you only need to do it once.
Either your method or what I described.
Long isn't problematic. There is a "long" in Swift, it's Int64. Having to wrap values like that isn't fun, but Kotlin and Swift are different languages, and there are compromises. If you use Int in Kotlin instead of Long, you'll need to wrap a Swift Int with Int32. A Kotlin Int is, in that sense, "problematic" in the same way. You need to specify which precision int you're using.
In Kotlin, List<Long> is a list of Long objects, while just a Long is a primitive value. Kotlin hides the boxing of those values, but they are boxed. The Swift/Kotlin interface is forcing you to be more explicit. If you want primitive values, use the ___Array forms mentioned above.

Related

Which F# type names and declaration syntax are considered idiomatic?

F# has multiple ways to declare the same types. This is likely because of the dual lineage of F# as both a member of the ML family and a .NET language. I haven't been able to find any guidance on which style is more idiomatic.
Specifically, I want to know:
Which is more idiomatic for 64-bit IEEE 754 floating-point numbers in F#, float or double?
Which is a more idiomatic way in F# to declare an array type:
int[]
int array
array<int>
Sources:
https://learn.microsoft.com/dotnet/fsharp/language-reference/basic-types
https://learn.microsoft.com/dotnet/fsharp/language-reference/fsharp-types#syntax-for-types
Context: I'm working on some API documentation that is explaining how data in a data store maps to .NET types, along with how those types are typically declared in both C# and F#.
For doubles, it's pretty much always float. Unless you deal with both singles and doubles and need to ensure clarity I guess.
For generic types, the usual syntax I use and see people use is:
int option
int list
int[]
For all other types, including F#-specific ones like Async, Set, and Map, angle bracket syntax is used.
The only type that I feel has a significant split is seq (an alias for IEnumerable): I'd say the majority of people use seq<int> but a significant number of people write int seq. Either way, you should definitely use seq and not IEnumerable. Similarly, you should use the alias ResizeArray for System.Collections.Generic.List.
The F# Core Library reference, which seems like a good example to follow, seems to prefer float, int[] and seq<int>.

Convert generic array to NSOrderedSet?

I need to assign return value of a fetch:
try! c.fetch(fr)
to a to-many relationship (itemsWithoutRatingOfLoggedInUser):
Utility.app(c: c).itemsWithoutRatingOfLoggedInUser = try! c.fetch(fr2)
And got following error. What can I do? I tried to cast with as! operator, did not help.
Casting (with as) is for cases where a value of one type can be interpreted as a value of some other, explicitly related type. This interpretation is defined in terms of language features: either type relationships (like inheritance or protocol conformance), or the handful of special cases where Swift can bridge Foundation or CF types to/from their Swift Standard Library equivalents.
When you cast, you're asking the Swift compiler/runtime to squint its eyes a little and pretend that one type is another. (Maybe even do a little twiddling behind the scenes so that pretending works.) Most often, casting happens when you have a value where you know more about its type than Swift (in the context of the function you're writing) does.
When you have types that aren't explicitly related though language features — that is, one isn't a subclass of the other, or one isn't a protocol adopted by the other, or they aren't one of the special sets of equivalent types from Foundation/CF that Swift knows how to bridge — you have to convert, not cast. (Swift also makes you convert instead of casting when types are semantically different enough that you need to think about the consequences of conversion, like when going between signed and unsigned integers.)
Array and NSOrderedSet are semantically different enough types that you have to convert, not cast.
Conversion between types requires that the type being converted to know about the type being converted from, so to perform a conversion you use an initializer of the target type.
let stuff = managedObjectContext.fetch(request)
let orderedSet = NSOrderedSet(array: stuff)
Note that NSOrderedSet is not a generic type in Swift 3, so even if you create it from a typed array ([MyObject]), the elements come out as Any. That's a use case for casting:
let item = orderedSet as! MyObject

What's the advantage of having a type to represent a function?

What's the advantage of having a type represent a function?
For example, I have observed the following snippet:
type Soldier = Soldier of PieceProperties
type King = King of PieceProperties
type Crown = Soldier -> King
Is it just to support Partial Application when additional args have yet to be satisfied?
As Fyodor Soikin says in the comments
Same reason you give names to everything else - values, functions,
modules, etc.
In other words, think about programming in assembly which typically does not use types, (yes I am aware of typed assembly) and all of the problems that one can have and then how many of those problems are solved or reduced by adding types.
So before you programmed with a language that supported functions but that used static typing, you typed everything. Now that you are using F# which has static typing and functions, just extend what you have been using typing for but now add the ability to type the functions.
To quote Benjamin C. Pierce from "Types and Programming Languages"
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
As noted in "Types and Programming Languages" Section 1.2
What Type Systems Are Good For
Detecting Errors
Abstraction
Documentation
Language Safety
Efficiency
TL;DR
One of the places that I find named type function definitions invaluable is when I am building parser combinators. During the construction of the functions I fully type the functions so that I know what the types are as opposed to what type inferencing will infer they are which might be different than what I want. Since the function types typically have several parameters it is easier to just give the function type a name, and then use that name everywhere it is needed. This also saves time because the function definition is consistent and avoid having to debug an improperly declared function definition; yes I have made mistakes by doing each function type by hand and learned my lesson. Once all of the functions work, I then remove the type definitions from the functions, but leave the type definition as comments so that it makes the code easier to understand.
A side benefit of using the named type definitions is that when creating test cases, the typing rules in the named function will ensure that the data used for the test is of the correct type. This also makes understanding the data for the test much easier to understand when you come back to it after many months.
Another advantage is that using function names makes the code easier to understand because when a person new to the code looks at if for the first time they can spot the consistency of the names. Also if the names are meaningful then it makes understanding the code much easier.
You have to remember that functions are also values in F#. And you can do pretty much the same stuff with them as other types. For example you can have a function that returns other functions. Or you can have a list that stores functions. In these cases it will help if you are explicit about the function signature. The function type definition will help you to constrain on the parameters and return types. Also, you might have a complicated type signature, a type definition will make it more readable. This maybe a bit contrived but you can do fun(ky) stuff like this:
type FuncX = int -> int
type FuncZ = float -> float -> float
let addxy (x:int) :FuncX = (+) x
let subxy :FuncX = (-) x
let addz (x:float) :FuncZ =
fun (x:float) -> (fun y -> x + y)
let listofFunc = [addxy 10;addxy 20; subxy 10]
If you check the type of listofFunc you will see it's FuncX list. Also the :FuncX refers to the return type of the function. But we could you use it as an input type as well:
let compFunc (x:FuncX) (z:FuncX) =
[(x 10);(z 10)]
compFunc (addxy 10) (addxy 20)

unsafe casting in F# with zero copy semantics

I'm trying to achieve a static cast like coercion that doesn't result in copying of any data.
A naive static cast does not work
let pkt = byte_buffer :> PktHeader
FS0193: Type constraint mismatch. The type byte[] is not compatible with type PktHeader The type 'byte[]' is not compatible with the type 'PktHeader' (FS0193) (program)
where the packet is initially held in a byte array because of the way System.Net.Sockets.Socket.Receive() is defined.
The low level packet struct is defined something like this
[<Struct; StructLayout(LayoutKind.Explicit)>]
type PktHeader =
[<FieldOffset(0)>] val mutable field1: uint16
[<FieldOffset(2)>] val mutable field2: uint16
[<FieldOffset(4)>] val mutable field3: uint32
.... many more fields follow ....
Efficiency is important in this real world scenario because wasteful copying of data could rule out F# as an implementation language.
How do you achieve zero copy efficiencies in this scenario?
EDIT on Nov 29
my question was predicated on the implicit belief that a C/C++/C# style unsafe static cast is a useful construct, as if this is self evident. However, on 2nd thought this kind of cast is not idiomatic in F# since it is inherently an imperative language technique fraught with peril. For this reason I've accepted the answer by V.B. where SBE/FlatBuffers data access is promulgated as best practice.
A pure F# approach for conversion
let convertByteArrayToStruct<'a when 'a : struct> (byteArr : byte[]) =
let handle = GCHandle.Alloc(byteArr, GCHandleType.Pinned)
let structure = Marshal.PtrToStructure (handle.AddrOfPinnedObject(), typeof<'a>)
handle.Free()
structure :?> 'a
This is a minimum example but I'd recommend introducing some checks on the length of the byte array because, as it's written there, it will produce undefined results if you give it a byte array which is too short. You could check against Marshall.SizeOf(typeof<'a>).
There is no pure F# solution to do a less safe conversion than this (and this is already an approach prone to runtime failure). Alternative options could include interop with C# to use unsafe and fixed to do the conversion.
Ultimately though, you are asking for a way to subvert the F# type system which is not really what the language is designed for. One of the principle advantages of F# is the power of the type system and it's ability to help you produce statically verifiable code.
F# and very low-level performance optimizations are not best friends, but then... some smart people do magic even with Java, which doesn't have value types and real generic collections for them.
1) I am a big fan of a flyweight pattern lately. If you architecture allows for it, you could wrap a byte array and access struct members via offsets. A C# example here. SBE/FlatBuffers even have tools to generate a wrapper automatically from a definition.
2) If you could stay within unsafe context in C# to do the work, pointer casting is very easy and efficient. However, that requires pinning the byte array and keeping its handle for later release, or staying within fixed keyword. If you have many small ones without a pool, you could have problems with GC.
3) The third option is abusing .NET type system and cast a byte array with IL like this (this could be coded in F#, if you insist :) ):
static T UnsafeCast(object value) {
ldarg.1 //load type object
ret //return type T
}
I tried this option and even have a snippet somewhere if you need, but this approach makes me uncomfortable because I do not understand its consequences to GC. We have two objects backed by the same memory, what would happen when one of them is GCed? I was going to ask a new question on SO about this detail, will post it soon.
The last approach could be good for arrays of structs, but for a single struct it will box it or copy it anyway. Since structs are on the stack and passed by value, you will probably get better results just by casting a pointer to byte[] in unsafe C# or using Marshal.PtrToStructure as in another answer here, and then copy by value. Copying is not the worst thing, especially on the stack, but allocation of new objects and GC is the enemy, so you need byte arrays pooled and this will add much more to the overall performance than you struct casting issue.
But if your struct is very big, option 1 could still be better.

Void in constrast with Unit

I would like to understand which is the difference between these two programming concepts. The first represents the absence of data type and at the latter the type exists but there is no information. Additionally, I recognize that Unit comes from functional programming theoretical foundation but I still cannot understand what is the usability of the unit primitive (e.g., in an F# program).
In functional programming, we usually speak of mapping inputs to outputs. This literally means mapping an argument to its return value(s). But if something is going to be a function in the mathematical/category-theory sense, it has to return something. A void value represents that a function returns nothing, which is nonsensical in these terms.
unit is the functional answer to void. It's essentially a type with only one value, (). It has a number of uses, but here's a simple one. Let's say you had something like this in a more traditional imperative language:
public static <T, U> List<U> map(List<T> in, Function<T, U> func) {
List<U> out = new ArrayList<U>(in.size());
for (T t : in) {
out.add(func.apply(t));
}
return out;
}
This applies a particular function func to every element on the list, producing a new list of func's output type. But what happens if you pass in a Function that just prints its arguments? It won't have an output type, so what can you put for U?
In some languages, passing in such a function would break this code (like in C#, where you can't assign void to a generic type). You'd have to resort to workarounds like having an Action<T>, which can get clunky.
This is where the concept of unit is useful: it is a type, but one that may only take on a single value. That greatly simplifies things like chaining and composition, and vastly reduces the number of special cases you have to worry about.
The unit type just makes everything more regular. To an extent you can think of every function in F# as taking a single parameter and returning a single result. Functions that don't need any parameters actually take "unit" as a parameter, and functions that don't return any results return "unit" as a result. This has a variety of advantages; for one, consider how in C# you need both a slew of "Func" delegates to represent functions of various arities that return values, as well as a slew of "Action" delegates that do not return values (because e.g. Func<int,void> is not legal - void cannot be used that way, since it's not quite a 'real' type).
See also F# function types: fun with tuples and currying

Resources