I agree and I have no problem with companies acting in their own self-interest - I’d be (pleasantly) surprised if that were not the case. But open source Java is better for all the rest of us than closed source Java fully in the hands of Oracle.
It’s possible I overstated things earlier. I’m not comfortable with the main language I use being held in such control by a corporation who, naturally, will act in their self-interest and not in the interests of Java developers - except where those interests collide. Were Java still closed source and owned by Oracle I’d be extremely uncomfortable - would I definitely move away from Java though? It depends on what options there were. I’m not sure that any other JVM languages could easily or legally exist without an OS JVM. The Oracle/closed source factor would be a significant negative for Java in my mind, but not necessarily enough to make me jump.
That all said, it is OS and I am considering a move away to other languages…
If you never had any issues with wildcards, then all the better xD I tried to say that there are cases where you need variant collections. Maybe this example is simple enough?
static class SuperClass {}
static class SubClass extends SuperClass {
public void subClassMethod() {}
}
static List<SuperClass> doSomething() {
List<SubClass> result = new ArrayList();
result.add(new SubClass());
for (SubClass current: result) {
current.subClassMethod();
}
return result; // Won't compile
}
You can’t return the collection here because of invariance. May look like an artificial example for some - if you or they don’t have had problems in this regard, complex generics can be skipped cocmpletely and stuff is unnecessary
One could now return List<? extends SuperClass> and everything is fine. But the user will have to deal with this, because he wants to use the result A better way would be to be able to declare the variance on type definition side. For example a readonly list would never ever allow to put elements into… For this case in comparison, Kotlin implements List as
interface List<out E>
so the type is automatically a producer and the user doesn’t have to look at variance stuff.
Yea, maybe not that important for most people, especially people new to the language. Nvm what I say
I dont like in kotlin 2 dots “:” and name var before type and return of function at the end
this was keep me away from kotlin, scala, groovy and other ^^
they all have same strange pattern in syntax(like they all was parsed by Xtext ;))
up: hm groovy don’t have them)) maybe in some past i find something different to not use it - need recheck ^^
Y, now i remember) it have some compile nightmares and this one of them http://www.gmarwaha.com/blog/2009/02/02/groovy-private-is-not-private/
(i even don’t know if they fix this and other bugs ^^)
I didn’t say I hadn’t had issues with wildcards, or didn’t understand the reasoning behind adding this (hey, I’m looking forward to JEP 300 ) … but that you were providing examples of doing things that are either not a problem to implement already or don’t make sense to do (including your last example).
I’m trying to give examples for the exact thing that JEP300 targets to solve, I thought!? I don’t have better examples than the one with the readonly list. In Java, one would have to change the return type of the doSomething() method and return a wildcard type. This is totally discouraged, because the problem then shifts to the user - could continue like this afterwards:
In Kotlin, exactly this scenario can be copy pasted (and auto transformed) and the code will compile, because type T in List is defined as…con…co…I don’t know, as out, so it is only produced.
No, you wouldn’t, you’d not create the wrong list in the first place (in your contrived example!). Of course there are real-world examples where this feature is necessary, but they’re thankfully quite rare, particularly with Streams, lambdas and better inference
eg. this works (peek is horrible, but so are side effects )
Yea I’m sorry, I can’t give you better examples than the ones I already gave you First of all, there are scenarios where you can’t use Java 8 features. Second, there absolutely is no “wrong” list in my example. Exactly this case appeared on my job where a deserializer returned a list of implementations (code not under my control). I …uhm… okay I don’t think I can satisfy your questions with proper examples, so maybe let’s stop pingpong here. However, distinction between consumer and producer is the heal to invariance. Declaration-site variance (and type projections), as available in Kotlin, eliminate the need for wildcards, hence eliminate said problems in a very simple and natural way, mostly without the user having to bother with it.
Oah, slowly I’m getting really annoyed here and I’m starting to understand why everybody hates us Java guys.
I’m a Java guy myself - so could we please stop with this “we know Java has faults” stuff and “Java can do things just fine” and have a talk about language design like adults? I clearly showed some examples, where a concept doesn’t work out. Since Java uses this concept only (yet), there’s no way around its downsides in first instance. It really doesn’t matter if you (or the guy next to you, or his friend) encounter this problem often or rarely, or if there exist some suspicious workarounds or (for the user) more than necessary complex solutions. If you guys (and me too) would be honest, the answer is “yes, this problem can’t be solved in a nice way with Java and we got used to it, because we have to suffer from it rarely”. Than nice for you. Are other people nevertheless allowed to talk about concepts, better solutions in a thread particularly dedicated to a language that doesn’t suffer (some of) these problems?
And your answer is exactly the reason why it’s necessary to post again and again. All your examples actually don’t compile fine. They compile with a warning. The first solution returns a raw type, which effectively means that no one can use the result in a typesafe way, as seen in example 4. If the interna of the doSomething method changes, the user’s code will fail at runtime with a cast exception. Example two and three are better, because you have higher chances to get a compile error when things change. However, the consumer/producer intention is gone now, as the user can afterwards freely add arbitrary subclass instances to list l2, or even arbitrary superclass instances to l3.
However. My only intention to post in this thread was to show people that Kotlin is at least on par with Java performance and code quality wise, and later to show phunni that Kotlin’s generics really make a lot of sense. I don’t have desire to post anything further as it seems the majority here isn’t interested in an exchange … just keep on coding however you want.
I what look how you broke list l2 at runtime after its exit Fun with class cast XD
up: Nope sorry - i don’t care XD
I know that generics is only compile time
– and clases don’t have any values from it
so you can’t check class in runtime with generic.class
I doubt that kotlin change this
So if its fails in java it may same fails in kotlin
You can’t count on generics - its only compile advices(same like annotations) – not 100% type save
public static void main(String[] args){
List<SuperClass> l2 = (List<SuperClass>) doSomething2();
//crash it runtime here
List<? extends SuperClass> l3 = doSomething2(); //and this
}
static class SuperClass {}
static class SubClass extends SuperClass {
public void subClassMethod() {}
}
//or after exit function
static List<? extends SuperClass> doSomething2() {
List<SubClass> result = new ArrayList<>();
result.add(new SubClass());
for (SubClass current: result) {
current.subClassMethod();
}
return result;
}
IMO can kotlin remove useless “:” overflow? - no? - f** it
up:
I hear same story couple years ago about Groovy – and all be fine until one day when enterprise start crashing in unknown place
– after spend couple weeks they find out that code compiles wrong by parser – no code errors in src code ^^
upp:
Its ok to show features,
but not ok repeat same text over and over every day
– we need move to constructive discussion)
I like Kotlin features, but don’t like syntax(text) overflow comparing with java
I personally found that Kotlin lets me write projects faster, and with better style (pure functions, immutable state). For small, throwaway games and utilities its definitely faster to write them in Kotlin. Type inference is nice but it makes the code less readable. You could write types in Kotlin but then you’re writing var or val unnecessarily anyway, so it’s a net loss from Java. Ideally you could have IDE support for writing var and it autoconverts to the return type of the expression you assign a variable to.
Kotlin makes it easier to write final variables, I like that, and the if/try/when as expressions as well. I do agree that Kotlin doesn’t seem as cohesive and well thought out as Java. I think the Scala style guide got it right in requiring explicit types for everything that isn’t assigned to a constructor or a string/int/float literal.
Kotlin eliminates a lot of boilerplate code and I will probably keep using it because of that. Games are write and throw away code most of the time so the loss in readability isn’t that bad while the increased development velocity is a big plus.
I wanted to post a screenshot here to show how you can make Kotlin render type inference in the IDE. As I was going through my code, I realized in how few places it’s actually necessary. If you remove obvious types like literals (val x = 10) and constructor calls (val foo = Foo()), I had a hard time finding a good example in lwjgl3. Probably because there are so many single-arg lambdas and I make extensive use of the implicit “it” argument. Anyway, I was more lucky in lwjgl3-vulkangen:
The grayed-out “: Foo” types are virtual, I didn’t have to type them. If the right-hand side expression changes, these types are updated automatically. Lots of "it"s in here too, but note how “feature” at line 114 is annotated. Surely, this convenience will be available for Java vars too.
A few other comments based on the discussion above:
Declaration/use-site variance and type projections: Yaaaaawn… Kotlin generics are indeed cleaner and more flexible than Java’s, and you can write pseudo-reified code with inline functions. But it’s still generics. There are no meta-programming features and you start hitting the inherent limitations as soon as you try to do anything half-complicated. Like in Java, I use Kotlin generics as little as possible (basically collection-style), anything else is a waste of time and effort.
Same for data classes, you can’t hear about Kotlin without hearing about data classes, but they are really not a big deal in practice. Btw, they’re coming to Java. Having the syntax in place will be useful for value types though.
Pattern matching is nice syntactic sugar. Very simple in Kotlin (when statement), Scala is more powerful there. But I honestly don’t get why people get excited about switching on types… since when is that considered good practice? OK, sucks when you have to do it without syntactic support, but if the support is there, it’s a huge magnet for novice programmers writing shitty code. Much more so than local type inference.
Explicit casts in Kotlin look like:
val src: Any = "test"
val trg = src as String
i.e. you write the type once, not twice.
% of Kotlin in LWJGL: It’s the (offline) code generator and binding templates. The generated Java and C code lives in a different repository. The classes you get when you download LWJGL are 100% javac compiled.
Top Kotlin features for me: extension functions/properties, null-safety/inference, anything that has to do with parameters (final-by-default, named params, default values, varargs, lambdas).
Now that @princec mentioned it, I would love to see a thread about Clojure and the practical pros and cons of using it. Also, any tips on how to get used to the alien syntax?
Because structural pattern matching is great (and a bit more than just switching on types). We’ve been fooled into thinking using the type system isn’t good OOP, rather than the reality that it’s currently error prone (compile-time safety isn’t just syntactic support) and Java just isn’t very good OOP!
+1. Now interestingly in the context of what I said above (Java not good OOP), I’ve been looking at the history of OOP a bit recently - I’ve read multiple people claim that Clojure is more in line with the original idea of OOP than Java is. ;D
I guess the only way to really get to grips with Clojure is to use it in anger. It is very alien but I seem to recall taking to it like a fish to water the last time I tried any functional programming.
The main problem with it is that it is not quite so neatly organised and pleasantly or logically named as Java, coming as it does from a background to make old beardy Lispers happy, rather than Java programmers happy.
Also be warned that it is not especially fast or efficient…
Getting started with game programming with Clojure
Getting started with game programming with Kotlin
and make both oriented for Java programmers.
Get a basic game loop going, and bounce a ball, with keyboard/mouse interaction (as I did with JavaFX).
Learning Clojure was very fun and weird. When I was looking at it, I also went through the first few MIT Structure and Interpretation lectures, and recoded them with Clojure. This was my first introduction to LISP-type structures and programming patterns. It is great help for getting your head around operations using function interfaces in chains. But I didn’t see it through to where I could figure out how to make a game with it.
Lisp-like languages are perfect candidates to write one’s own interpreter/compiler for. That’s where I used them before. But i really can’t imagine how a game written with clojure would look like, so I would be interested in a Tutorial as well
Yes, But normally it is implemented with inheritance, because business logic for a couple different implementations in one method/class seeeeeeems to be Bad practice. And now everyone wonders why the big switch case returns everywhere xD
Man did I really not mention that virtual type rendering from the IDE? I should have. It does seem to address at least some of the problems mentioned here. Not yet in 7 months of programming in Kotlin has something being the wrong type been an issue that wasn’t just design-related.
I could make a basic tutorial for getting some stuff working too - maybe I’ll start work on that now?