Scala arrays and parameterized types - arrays

I'm trying to define a generic class that takes a parameterized type T and then use the type in an Array definition in the class. I wrote the following which I thought seemed like it should work
class MyClass[T] {
val myarr:Array[T] = new Array[T](10)
}
But the compiler complains with the following
can't find the class manifest for element type T
value newArray is not a member of Null
Anyone know whats going on here and what its not happy about?

The compiler needs to know how to instantiate things of type T. In the traditional Java way of handling generics through type erasure, this cannot reasonably be done; the compiler just says, "Hey, I don't know what T is, so I don't feel so great about allowing you to instantiate a T like that." In Scala, however, there is a word-around for this: manifests. In order to include the manifest for T, just change the first line of that code to
class MyClass[T : Manifest] {
That's it.

Related

Check if generic is an array with inline function

How can I check if a Generic is an Array using an inline function?
I tried with the following code:
class Mediator {
inline fun <reified C> mediate(string: String): Container<C> {
if (C::class == Int::class) {
//It works
}
else if (C::class == Array::class) {
//It doesn't work!
}
throw IllegalStateException("Yopta")
}
}
But it doesn't work. Maybe because it can be Array<Whatever>?
How can I do it?
Contrary to collections where for example List<String> and List<Int> are internally represented by the same class List, in arrays the type parameter is a part of the type itself. That means Array<String> and Array<Int> are internally represented as different types and as far as I know, they don't have a common super type.
I don't know a pure Kotlin solution to check if a class is an array. It seems to me like an overlook in the design of the reflection API. If you don't mind using the Java reflection, you can do it like this:
else if (C::class.java.isArray) {
Update
There is one interesting fact here. In the Kotlin type system we could consider Array<out Any?> to be a supertype of all arrays. For example, we can upcast to it without an explicit cast operator:
val intArray = arrayOf(1, 2, 3)
val arr: Array<out Any?> = intArray
However, for the reflection API these two types are entirely different:
// false
println(Array<Int>::class.isSubclassOf(Array<out Any?>::class))
I assume this is due to how arrays where implemented in Java. I'm not even sure if it would be technically possible to return true in the code above. Still, it is concerning it provides a different result than the type system at a compile time and it doesn't even produce a warning.
Actual answer that solves the issue here.
Since broot added an actual answer I'll just leave this here as a note as to how we can see that he is right basically.
If we make the call like this:
Mediator().mediate<Array<Int>>("")
Adding a simple check inside the function like this makes it a bit confusing as to why they are not equal.
println(C::class) //class Kotlin.Array
println(Array:class) //class Kotlin.Array
But doing the same for the underlying java class shows that they are not really the same object.
println(C::class.java) //class [Ljava.lang.Integer
println(Array:class.java) //class [Ljava.lang.Object
So changing the statement to:
if(C::class.java == Array<Int>::class.java)
Will make the example work ... for Int only. All other "infinite" possibilities will have to be added manually. Not an issue if you just want to check Array<X> only, but definitely not generic.

Kotlin array types and class literals

I am trying to deserialize an array of JSON objects with GSON. So the simple call:
val arrayOfFoo = gson.fromJson(source, Array<Foo<*>>::class.java>)
should do the trick. But type erasure tells us, that Foo<*> does not exist at runtime, so the error "Only class literals are allowed on the left hand side of a class literal" pops up. Well, so the solution must be:
val arrayOfFoo = gson.fromJson<Array<Foo<*>>>(source, Array::class.java)
Unfortunatelly, now the Kotlin compiler magic - that turns arrays of Wrapper types into primitive arrays - can not be sure what to do and tells us:
"Array class literals require a class type. Please specify one in angle brackets".
But, wait: This is, what did not work a second ago. Using
Array<Foo>::class.java
does not work, too, since now the compiler tells us: "One type argument is expected for Foo".
I personally can not see a way to solve that. Is it impossible to give a class literal of a typed array, which's type also expects a type parameter?
You can get the array class from an array instance, for example either one of
arrayOf<Foo<*>>()::class.java
java.lang.reflect.Array.newInstance(Foo::class.java, 0)::class.java
The basic problem: You need to specify the type of your array. This is done using a TypeToken in Gson.
I hope this helps:
val listType = object : TypeToken<Array<String>>() {}.type
val json = """["1"]"""
val yourClassList :Array<String> = Gson().fromJson(json, listType)
print(yourClassList)
Note that for primitives, it is simpler: Gson().fromJson(json, IntArray::class.java)

use of any in typescript

I have an angular 1.4 project on typescript, the project is getting bigger and bigger and our team is really tired of interfaces that we have declared (so that all objects are typed, in comparison to any)
I'm asking if this is a good idea or not? I chose typescript because I wanted to have a typed project, should I drop the interfaces or not?
You can get by without using interfaces and going with any, but in the long term you are probably going to regret it. If your team is sick of the interfaces you've created, I would put time in fixing those instead of abandoning them. There is a significant argument around if typed languages reduce the number of errors found in code. Personally, I think they do.
What I've found with typed languages is that it helps remove stupid mistakes we all make, and this clears up our time to focus on actual logic problems in code. Not everyone agrees with me on this, but I will always pick a type language over a non typed one, especially if the team is used to dealing with languages like Java or C#.
Interfaces can be very helpful if used properly.
If you are just doing this....
IFoo { ... }
Foo implements IFoo { ... }
Then they will not help as much as they do in other typed languages (C#/Java). Because the type checking in TypeScript is dependent upon the properties on the object and NOT on the declared type. This is because you can simply write this...
MyCtrl (foo: Foo) { ... }
//instead of
MyCtrl {foo: IFoo) { ... }
This will not hinder unit testing in any way since as stated above the type checking is based upon properties and not declarations.
There are cases when interfaces can be quite helpful, for instance a common use case is when defining an object as a parameter...
doSomething (options: ISomethingOptions) { ... }
There is no harm in creating interfaces for everything, you just need to determine what level of typing works best for your team.

D: Creating an array of templated objects

I'm trying to create an array of Regex objects, like so: Regex[] regexes;.
The compilation fails with main.d(46): Error: template std.regex.Regex(Char) is used as a type.
I find the documentation cryptic. All I understand is that templates generate code on compilation, but I don't see what's preventing me from creating an array of Regex.
There's an existing question on StackOverflow with the same problem, but it deals with C++, not D.
You cannot create a regex object without first instantiating the template with a type. this is because the actual type is generated at compile time based on the instantiation type you give. Regex itself is not an actual type, it is just a template function allowing you to generate a type when instantiated.
In this case you probably want to change:
Regex[] regexes;
into:
Regex!char[] regexes;
to tell the compiler that your regex contains chars as opposed to some derived type. This means specifically you are instantiating the Regex template with the type char.

How can I use an F# type with generics in Silverlight 4 and XAML?

Take the F# following code:
type Blah<'T>(objects : 'T array) as this = // whatever
When I try to use that type in a XAML document, there is no type associated with the generic parameter, and it's ugly. I think the compiler complains, too:
<ns:Blah foo="bar"/>
So, I try to alias the type like so (at the bottom of my Blah.fs file):
type StuffBlah = Blah<Stuff>
Then when I use it in the same way in my XAML document, the type is not found to exist:
<ns:StuffBlah foo="bar"/>
Why is that? Is there a cleaner, more elegant way to do this? I'm still getting the hang of Silverlight, XAML, and F#, so any advice would be greatly appreciated. Thanks.
The reason the StuffBlah version doesn't work is that particular piece of F# syntax creates a type alias only for the F# project vs. creating an actual type. Since the name is not visible at the IL level as an actual type it is not accessible to Silverlight or XAML in general.
One way to work around this is to create StuffBlah as a first class type which derives from Stuff<'T>. Not ideal at all but it will work.

Resources