What is the idiomatic way of parsing ("5", "6") to (5, 6)? I have already tried calling .map(String::parse::<usize>) but that doesn't work because tuples are not iterators. Nor can I call .into_iter().
Tuples are meant to be heterogeneous collections and as such you can't really iterate over them, as different elements can, in principle, have different types.
So the easiest way is just
let a: usize = my_tuple.0.parse()?;
let b: usize = my_tuple.1.parse()?;
and if you need something more "sophisticated" you'll have to use a macro:
How to iterate or map over tuples?
This might seem unnecessarily cumbersome when you compare it with Python, where tuples are indeed iterable. But that's because you have dynamic and duck typing in Python, so the fact that tuples can be heterogeneous (different datatypes in different positions) isn't that big of a deal.
Think about it. What would even the signature be for the closure to pass to map in a tuple of type, say, (i32, String, Option<f64>)?
Related
I want to model fixed-size arrays that can contain records and other fixed-size arrays. I then want to model store and select accesses to them.
I currently use ArraySorts for the arrays and Datatypes for the records. However, according to this answer (arrays) and this answer (records), these aren't really intended for my usecase. Is there anything else in Z3 I could use instead?
Background: I want to model pointers as they occur in the LLVM IR. For this, each pointer has a data array that represents the memory buffer into which it is pointing and an indices array that represents the indices used in getelementptr calls. Since the memory buffer could contain pointers or structs, I need to be able to nest the arrays (or store the records in arrays).
An example (in z3py) looks like this:
Vec3 = z3.Datatype("Vec3")
Vec3.declare("Vec3__init",
("x", z3.IntSort()),
("y", z3.IntSort()),
("z", z3.IntSort())
)
Vec3 = Vec3.create()
PointerVec3 = z3.Datatype("Pointer__Vec3")
PointerVec3.declare("Pointer__Vec3__init",
("data", z3.ArraySort(z3.BitVecSort(32), Vec3)),
("nindices", z3.IntSort()),
("indices", z3.ArraySort(z3.IntSort(), z3.BitVecSort(32)))
)
PointerVec3 = PointerVec3.create()
Arrays and records are the only way to model these things in z3/SMT-Lib. And they can be nested as you wish.
It is true that SMTLib arrays are not quite like arrays you find in regular programming languages. But it's not true that they are always unbounded. Their size exactly matches the cardinality of their domain. If you want a bounded array, I recommend using an appropriate BitVec type for your source. For an n-bit bit vector, your array will have 2^n elements. You can work with a small enough n, and treat that as your array; which typically matches what you see in practice: Most of such internal arrays will be a power-of-two anyhow. (Moreover, provers usually don't do well with large arrays; so sticking to a small power-of-two is a good idea, at least to start with.)
So, these are your only options. Stack-overflow works the best if you try it out and actually ask about what sort of problems you ran into.
Taking the example of writing a parser-unparser pair for a DU.
The unparser function of course uses match expression, where we can count on static exhaustiveness check if new cases are added later.
Now, for the parsing side, the obvious route is (with eg FParsec) use a choice parser with a list of the DU case parsers. This works, but does not have exhaustiveness checking.
My best solution for this, is to create a DU_Case -> parser function that uses match expression, and using runtime reflection get all DU cases, call the function with them, and pass the so generated list to the choice combinator. This works, and does have static exhaustiveness checking, BUT gets pretty clunky fast, especially if the cases have varying fields.
In other words, is there a good pattern other than using reflection for ensuring exhaustiveness when the discriminated union is the output and not the input?
Edit: example on the reflection based solution
By getting clunky, I mean that for every case that has fields, I have to also create the field values dynamically, instead of the simple Array.zeroCreate(0) which is of course always valid. But what in the else branch? There needs to be code to dynamically create the correct number of field values, with their correct (possibly complex) constructors and so on. Not impossible with reflection, but clunky.
FSharpType.GetUnionCases duType
|> Seq.map (fun duCase ->
if duCase.GetFields().Length = 0 then
let case = FSharpValue.MakeUnion(duCase, Array.zeroCreate(0))
else
(*...*)
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.
How can I increase the length of a tuple in Erlang? For example, suppose Tup={1,2,3}, and now I want to add another element to it. Is there any way to do this?
Tuple is not suppose to be a flexible data structure. If you are resizing it often, then you should consider using other erlang data structures like lists, maps or sets - depends on your expectation. Here is nice introduction to key-value stores.
But if you really have to extend that tuple, then you can use erlang:append_element/2:
{1,2,3,4} = erlang:append_element({1,2,3}, 4).
Tuples aren't mutable so you can't, strictly speaking, increase the length.
Generally, if you want a variable-number-of-things datatype, a tuple will be very inconvenient. For example, iterating over all elements of a list is highly idiomatic, while iterating over all elements of a tuple whose size is unknown at compile-time is a pain.
However, a common pattern is to get a tuple as a result from some function and return elements of that tuple plus additions.
country_coords(Name) ->
{Lat, Lng} = find_address(Name),
{_Street, _City, _Zip, Country} = geocode(Lat, Lng),
{ok, Lat, Lng, Country}.
erlang:append_element(tuple_whose_length_to_increase, element_to_be).This is the inbuilt function but tuples,lists are not meant to be flexible.So avoid using this function unless there is no other way
Seq.windowed in F# returns a sequence where each window within is an array. Is there a reason why each window is returned as an array (a very concrete type) as opposed to say, another sequence or IList<'T>? An IList<'T>, for example, would be sufficient if the purpose was to communicate that the items of the window can be randomly accessed but an array says two things: elements are mutable and randomly accessible. If you can rationalise the choice of array, how is windowed different from Seq.groupBy? Why does that latter (or operators in the same vein) not also return the members of a group as an array?
I'm wondering if this is simply a design oversight or is there a deeper, contractual reason for an array?
I do not know what is the design principle behind this. I suppose it might just be an accidental aspect of the implementation - Seq.windowed can be quite easily implemented by storing items in arrays, while Seq.groupBy probably needs to use some more complicated structure.
In general, I think that F# APIs either use 'T[] if using array is the natural efficient implementation, or return seq<'T> when the data source may be infinite, lazy, or when the implementation would have to convert the data to an array explicitly (then this can be left to the caller).
For Seq.windowed, I think that array makes a good sense, because you know the length of the array and so you are likely to use indexing. For example, assuming that prices is a sequence of date-price tuples (seq<DateTime * float>) you can write:
prices
|> Seq.windowed 5
|> Seq.map (fun win -> fst (win.[2]), Seq.averageBy snd win)
The sample calculates floating average and uses indexing to get the date in the middle.
In summary, I do not really have a good explanation for the design rationale, but I'm quite happy with the choices made - they seem to work really well with the usual use cases for the functions.
A couple of thoughts.
First, know that in their current version, both Seq.windowed and Seq.groupBy use non-lazy collections in their implementation. windowed uses arrays and returns you arrays. groupBy builds up a Dictionary<'tkey, ResizeArray<'tvalue>>, but keeps that a secret and returns the group values back as a seq instead of ResizeArray.
Returning ResizeArrays from groupBy wouldn't fit with anything else, so that obviously needs to be hidden. The other alternative is to give back the ToArray() of the data. This would require another copy of the data to be created, which is a downside. And there isn't really much upside, since you don't know ahead of time how big your group will be anyways, so you aren't expecting to do random access or any of the other special stuff arrays enable. So simply wrapping in a seq seems like a good option.
For windowed, it's a different story. You want an array back in this case. Why? Because you already know how big that array is going to be, so you can safely do random access or, better yet, pattern matching. That's a big upside. The downside remains, though - the data needs to be re-copied into a newly-allocated array for every window.
seq{1 .. 100} |> Seq.windowed 3 |> Seq.map (fun [|x; _; y|] -> x + y)
There is still the open question - "but couldn't we avoid the array allocation/copy downside by internally only using true lazy seqs, and returning them as such? Isn't that more in the 'spirit of the seq'?" It would be kind of tricky (would need some fancy cloning of enumerators?), but sure, probably with some careful coding. There's a huge downside to this, though. You'd need to cache the entire unspooled seq in memory to make it work, which kind of negates the whole goal of doing things lazily. Unlike lists or arrays, enumerating a seq multiple times is not guaranteed to yield the same results (e.g. a seq that returns random numbers), so the backing data for these seq windows you are returning needs to be cached somewhere. When that window is eventually accessed, you can't just tap in and re-enumerate through the original source seq - you might get back different data, or the seq might end at a different place. This points to the other upside of using arrays in Seq.windowed - only windowSize elements need to be kept in memory at once.
This is of course pure guess. I think this is related to the way both functions are implemented.
As already mentioned, in Seq.groupBy the groups are of variable length and in Seq.windowed they are of a fixed size.
So in the implementation from Seq.windowed it makes more sense to use a fixed size array, as opposed to the Generic.List used in Seq.groupBy, which btw in F# is called ResizeArray.
Now to the outside world, an Array though mutable is widely used in F# code and libraries and F# provides syntactic support for creating, initializing and manipulating arrays, whereas the ResizeArray is not that widely used in F# code and the language provides no syntactic support apart from the type alias, so I think that's why they decided to expose it as a Seq.