Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (804)
Games in Android Showcase (237)
games submitted by our members
Games in WIP (867)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 2 [3] 4 5 6
  ignore  |  Print  
  Move to Kotlin?  (Read 42729 times)
0 Members and 1 Guest are viewing this topic.
Offline philfrei
« Reply #60 - Posted 2017-11-07 20:04:25 »

Maybe because I am "old" I very much appreciate @princec's take on variable types. There may be a few situations where the use would be benign, where the type doesn't matter and thus having to specify it is, indeed, "noise." But I think it is legitimate to worry that the feature will be abused and overused.

I am reminded of the old saw "a place for everything and everything in its place." Drives kids nuts, and for good reason: they are much more capable of remembering where everything is and don't see the motivation. Since they are pretty much bounded to a smaller area than adults, it is much easier for them to keep track of things.

With age and increased responsibility, the amount of information that you can or care to clutter your head with gets much smaller. It definitely adds to the cost of context switching, with trying to move between multiple projects.  Carrying trivial crap around like what the dang variable is or isn't is an aggravating nuisance. It's like having to continually stop for commercials when you just want to watch your movie. I am now experiencing the so-called joys and freedom of *var* with the JavaScript/VR project I'm working on, and am finding it a considerable annoyance with both debugging and with code-reading libraries and examples.

What is the term? Ah, here it is: technical debt

[EDIT, restatement of the controversy in terms of cognitive activity: is it more or less burdensome to mentally block out a bit of redundant "noise" than to carry additional facts in working memory? ]

music and music apps: http://adonax.com
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #61 - Posted 2017-11-07 20:12:05 »

Omg. I won't comment this as it seems you are simply not interested in getting better. I can't bei the only one who finds this hilarious.
If I weren't interested in improvement I wouldn't be so keen on Ceylon now, would I. Or Clojure, for that matter. (which I am)

Cas Smiley

Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #62 - Posted 2017-11-07 20:16:53 »

... and nor would I have been interested in generics. Nor Java in the first place. Nor would I be looking forward to value types, or reified generics.
I am not sure how you conflate my fairly clearly reasoned distaste for the concept of the var keyword with whether I want to "improve" or not, given that I'm clearly looking forward to all sorts of other changes (Hint: I don't really need to improve myself much in the field of computer science  - I'm already close to the top of the game I need to be in - further "improvement" won't get me anywhere I want to be)

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline cygnus
« Reply #63 - Posted 2017-11-07 21:52:58 »

I've been working in Kotlin for the last 5 months. It's a joy. There is without a doubt a much faster idea to code time, and as a result code is cleaner and more functional. I didn't read all the replies in this thread, but I did notice princec and phil's thoughts on dynamic typing. If the issue is variable type not being obvious, IntelliJ will automatically add in "ghost text" that tells you the type of the variable where it is declared. This way, you don't have to type (in the keyboard sense XD) it, but you can be sure what type it is when you write it or look at it again. Also, if there was any question at all about java interop, the audiocue library from phil works after just putting it in the library folder, as you would do on a java project. There is nothing else needed! It's great! (both Kotlin and AC Wink) <- o shit the https://xkcd.com/541/ situation (edit - never mind it turns into an emoticon)

I'm not sure if anybody else mentioned this, but Kotlin has pretty strange generics. The "in" and "out" system is less intuitive than Java's, I think, because the words don't really _mean_ anything from the start. Other than that, I have no complaints. 8000 lines in 4000, and less than a week of practice (not counting that I get from actually porting the code and then writing new stuff)

Offline cygnus
« Reply #64 - Posted 2017-11-07 21:57:55 »

Also, h.pernpeintner, you need to be considerate. Just because he doesn't agree with you doesn't mean he doesn't want to get better... he had (completely true) point that it's often a result of practices being ingrained over the years that makes him (and phil) not want to change (not trying to be like haha you're old Tongue)

I'm very excited about Kotlin too, but respect people who aren't. The very nature of programming is that it tends towards efficiency anyways, so if Kotlin turns out to be very good (which I think it will), people will just use it. And it spirals upwards from there, accelerated by its java interop.
Offline Opiop
« Reply #65 - Posted 2017-11-07 22:40:16 »

It's never safe, and throws CCE at runtime. But as we're assigning something to a String we may as well assume we're casting to a String to allow it to happen as we've effectively said exactly that we want to do that by declaring the destination to be of String. If the cast is possible, then why not? If the cast is not possible, javac will complain anyway.

Omg. I won't comment this as it seems you are simply not interested in getting better. I can't bei the only one who finds this hilarious.

Princec actually brings up a good point, there's 0 reason (from what I can think of right now) to declare the type of a variable and then have to retype the type when you're trying to cast. You're clearly in the camp of "less syntax", so why is what Princec said hilarious? It seems that you two would actually agree on the casting point.

But the whole type debate - I have a love/hate relationship with dynamic typing. If I'm working on a small personal project where I can keep all of the object definitions in my head while working then I love dynamic typing. It's not *that* much less typing, but it does save me a tiny bit of work that adds up over time. But on the flip side, if I'm reading someone's code or I'm working in a corporate setting then absolutely, I want my types defined right there in front of me. It's extremely painful to go hunt around a large codebase, connecting the dots and figuring out what type something actually is. Phil mentioned context switching and I completely agree with that - IMO its important that you give your mind a break and just let your work be as easy as possible. Hunting for types is trivial and is unnecessary work that you shouldn't have to deal with when you're trying to figure out the maze that large codebases can be.

I think there's fairly clear uses for either dynamic or static typing. I love NodeJS and Java for vastly different reasons and use them in far different ways.
Offline nsigma
« Reply #66 - Posted 2017-11-07 23:05:09 »

Princec actually brings up a good point, there's 0 reason (from what I can think of right now) to declare the type of a variable and then have to retype the type when you're trying to cast. You're clearly in the camp of "less syntax", so why is what Princec said hilarious?

How about because having the same syntax for a standard assignment (which can't throw a CCE) and a casting assignment (which can throw CCE) is a daft idea? Fine make it "less syntax" but at least make it an explicit action to move type checking to runtime.

Now if var in Java supports casts you'll be able to just write the type once without duplicating syntax!  Wink

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline philfrei
« Reply #67 - Posted 2017-11-07 23:15:11 »

Very nice to hear AudioCue works with Kotlin!

I'm wondering if this means that Kotlin's interop with Android means that AudioCue can be used with Android via Kotlin? There are basically just a couple IO functions (SourceDataLine and AudioInputStream) that rely on the javax.sound.sampled. Everything else in it is vanilla Java. I was assuming that for AudioCue to work with Android, it would be a matter of recoding the two IO points, and accepting the higher latencies that come with Android devices.

Suggestion that I might be afraid of change or stuck with ingrained practices is kind of hilarious. I hadn't even see my first line of Java code until into my 50's, something like 8 years ago.

music and music apps: http://adonax.com
Offline cygnus
« Reply #68 - Posted 2017-11-07 23:31:25 »

Sorry phil and princec, my bad. Didn't mean to insult you or anything (I read it over and it does kind of sound dumb, sorry :/). I hope you understand my general point though, but I guess if it doesn't apply to you it doesn't matter much. (I kind of took your mention of age and jumped off a cliff with it I guess haha)
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #69 - Posted 2017-11-07 23:31:35 »

How about because having the same syntax for a standard assignment (which can't throw a CCE) and a casting assignment (which can throw CCE) is a daft idea? Fine make it "less syntax" but at least make it an explicit action to move type checking to runtime.
I concede that's a disadvantage.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #70 - Posted 2017-11-07 23:33:14 »

Yeah, "ingrained" is not perhaps the right way to describe how us old-timers operate. Over the decades we've found that some things work a lot better than others.

Cas Smiley

Offline cygnus
« Reply #71 - Posted 2017-11-07 23:42:53 »

Deservedly cautious maybe?
Offline philfrei
« Reply #72 - Posted 2017-11-08 00:03:05 »

Standard Operating Procedure, for me:
1) try various approaches
2) pick best
3) test choice occasionally against variants, go back to 2.

music and music apps: http://adonax.com
Online elect

JGO Knight


Medals: 72



« Reply #73 - Posted 2017-11-08 09:20:13 »

With or without IDE is not the point.

No, but it does matter though.

A major part of my last 22 years as developer was reading other people's code. And one thing's for sure: that sucked. Everybody's thinks he's such a great coder. Which is rarely the case. Not to speak of producing readable code.

What sucked? Reading other people's code or reading shit code (or both)? Anyway the topic is a new language here.

And before jumping on the conclusion that inferred types makes the language less readable, I'd strongly suggest you to try to use the language first (for something more than an hello program) and draw your own conclusion.

Because judging a language without even trying it's really pointless.

Many people are already using it in production, is always one of the most loved in the charts. I don't want you to trust us when we tell kotlin is great or the other when they say is bad, but I'd like you to just give it a try.

Wouldn't be some of your time worth trying something that you may potentially like and use?
Offline h.pernpeintner

JGO Ninja


Medals: 107



« Reply #74 - Posted 2017-11-08 10:50:28 »

Princec actually brings up a good point, there's 0 reason (from what I can think of right now) to declare the type of a variable and then have to retype the type when you're trying to cast. You're clearly in the camp of "less syntax", so why is what Princec said hilarious? It seems that you two would actually agree on the casting point.
His (and my) points are usually about better code in general - I think it's clear that we're not talking about "less syntax". Less syntax is preferable if the intent remains clear and the readbility is enhanced. I won't say less syntax is a general solution. In fact, I tend to say the opposite most times. In this discussion we talked about possibilities to enhance readability by leaving out information that is not needed (yea, I got it, if I use a text editor than it is needed). Hilarious is his example (see below), not his opinion about val/var - although it should be clear that I have no sympathy for argumentation that starts with "but when I open it in my text editor".

His counter example ... I really try to find nice words for this. It was basically a suggestion to add better syntax for an implicit (always) unsafe (it circumvents compile time safety) cast. Two possibilities: Either I am missing a big thing here (and I am open for a hint here), or we are talking about something that every Java programming noob knows should be prevented at all costs.

The baseline here is, that you really can't have a discussion about language features and code readability, is these are the foundations...

But the whole type debate - I have a love/hate relationship with dynamic typing. If I'm working on a small personal project where I can keep all of the object definitions in my head while working then I love dynamic typing. It's not *that* much less typing, but it does save me a tiny bit of work that adds up over time.

Dynamic typing and type inference should never ever be said in the same sentence. It should never ever be confused - languages like JS having var vor variable type...with type inference you have a variable and a value. Two completely distinct concepts. With type inference you have the convenience (what people like about dynamic languages) and the safety (what people like about static languages) from both worlds. The "tiny bit" you mentioned is the key. The truth is: The types aren't gone. But they don't bother you any more in some situations. As without type inference, there is and will be no need to keep types in the head etc.

But on the flip side, if I'm reading someone's code or I'm working in a corporate setting then absolutely, I want my types defined right there in front of me. It's extremely painful to go hunt around a large codebase, connecting the dots and figuring out what type something actually is. Phil mentioned context switching and I completely agree with that - IMO its important that you give your mind a break and just let your work be as easy as possible. Hunting for types is trivial and is unnecessary work that you shouldn't have to deal with when you're trying to figure out the maze that large codebases can be.

I think there's fairly clear uses for either dynamic or static typing. I love NodeJS and Java for vastly different reasons and use them in far different ways.

I hope it's clear by now that we're not talking about dynamic typing (and I personally hate dynamic typing, believe me). The thing is: You can understand type inference as the distraction free mode... as I explained before, you most often don't need to know the exact type, it's sufficient if the type is there. But you think you want to know, if you never really used the system, like elect just says it. And that makes this discussion so painful for everyone. Look, the exact same discussion was done when C# introduced the feature ten years ago. And scala has it. And swift has it. And Ceylon has it. And pretty much everytime it was the same: The conservative people with no experience with this feature say "no you can't do it" and everyone else is totally satisfied with it. Can't say more about it.
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #75 - Posted 2017-11-08 11:33:47 »

I've got pretty extensive experience of type inference through lambdas which I've been using happily since they were available in EA. Although it's made the code a bit less busy on-screen it has caused numerous issues:

1. The IDE can get awfully confused and it seems to break all sorts of little things in the editor until you've fully formed your lambda expression...
2. ...a task made harder because the IDE can no longer figure out how to do it for you, rendering it little better than Textpad, and you suddenly realise just how dependent you are on the IDE doing 1000 little things to make editing code easier when it stops doing it.
3. When looking at code written some time back it is frequently completely opaque to you as to what the types of the arguments are in the lambda. Much is just hidden away as if it's not important to understanding what it is doing... but it is. Very important. You often have no direct idea even what interface the lambda was implementing if there is potential for similar looking possibilities.
4. You can get around most of that by ... declaring the types of all the arguments. Duh Smiley

However... as I said earlier, lambdas save so much cluttering boilerplate that these disadvantages are generally outweighed by the advantages by a pretty substantial margin of win. The type inference has been improved in Java 9 too, so all's good.

Regarding the type inference in the automatic cast: as I say, I concede that it theoretically opens the possibility of any assignment throwing CCE instead of just ones you were explicit in acknowledging with a cast. But if you came at it from a totally fresh viewpoint that trained you to understand that all assignments can throw CCE from the get-go, you would simply accept it as the way things were. Things would be different if CCE was a checked exception - but it is not. It is a runtime exception. You can in theory apply the same argument to array indexing: any array index can in theory be an IOOBE, but for some reason this doesn't bother you. That's because it's always been that way, and it's a runtime exception, not a checked exception.

Cas Smiley

Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #76 - Posted 2017-11-08 11:39:00 »

Btw regarding point 3 above: I have found that the quickest and easiest way out of this hole is, depressingly, to use Eclipse to refactor the lambda back into an anonymous implementation! Thus telling me what interface it was, what the arguments were, and even allowing me to easily go look at the Javadoc for it. Kinda ridiculous really that this is the quickest way of understanding what the hell it is in front of you at a glance. (Then I refactor it back into a lambda. Fortunately Eclipse makes this easy... but I often don't have source code in Eclipse when I'm trying to decipher it).

Cas Smiley

Offline matt_p
« Reply #77 - Posted 2017-11-08 12:12:07 »

Text about refactoring in eclipse

Hmm... how do I refactor all my anonymous inner classes to lambda automatically in eclipse? Couldn't find it yet :/

@topic
Well, personally I have no experience with Kotlin, but I like its smart casts:
1  
2  
3  
MyClass a = ...;
if(a is SubClassOfMyClass)
   a.useSubClassMethod();

is in Java
1  
2  
3  
MyClass a = ...;
if(a is SubClassOfMyClass)
   ((SubClassOfMyClass)a).useSubClassMethod();

or with further usage
1  
2  
3  
4  
5  
6  
MyClass a = ...;
if(a is SubClassOfMyClass) {
   SubClassOfMyClass castedA = (SubClassOfMyClass)a;
   castedA.useSubClassMethod();
   castedA.useAnotherSubClassMethod();
}

This is just a small visual thing, I would really like that for Java with instanceof operator Smiley
Offline h.pernpeintner

JGO Ninja


Medals: 107



« Reply #78 - Posted 2017-11-08 12:15:45 »

Okay I got it. There is simply no way of rescuing you from the last 30 years of your life and I won't further try it. The fact that you are mixing type inference with lambdas and local variable type inference alone and that you have problems reading and/or understanding Java's functional interfaces usage is enough, although you are such an experienced developer. As mentioned too many times again, there are situations where some concepts are not appropriate. For example it should be clear that using lambda stuff everywhere could be a sign of bad code - just as anonymous classes can make code totally unreadable, where lambdas are appropriate.

Besides is mentioned (to have something for the original topic again), that in Kotlin you have proper function types, so no interfaces involved (directly) here.
Offline Icecore
« Reply #79 - Posted 2017-11-08 12:18:27 »

I can also discuse all that but: there is no big difference in language and code itself
if its return same result and pass all Tests on it.
if code crushes in runtime then its Test error and not code itself

up:
There is a difference between:
Test on Refactoring
and
Test on function (class, module) result and entering params)

p.s Writing “result” Test is hard
- (TD) ("4" "3" "12")("-4" "3" "-12")("4" "-3" "-12")("-4" "-3" "12")
("0" "3" "0") ("4" "0" "0")("0" "-3" "0")("-4" "0" "0")("0" "0" "0")

– because on practice you fully write again tested function(TF) that produce same result without optimizations
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
int Mul(int v1, int v2){
   if(v1 == 0 || v2 == 0){
      return 0;
   }
   int sum = 0;
   int v2_A = v2;
   if(v2 < 0) v2_A = -v2;
   for(int i = 0; i < v2_A; i++){
      sum += v1;
   }
   if(v2 < 0) sum = -sum;
   return sum;
}

-And about TIF(TE) – I not so smart to even write test data for it XD
1  
2  
3  
4  
5  
-& < v1 < &
-& < v2 < &
v1 == 0 {0}
v2 == 0 {0}
r=0 0..(A(v2))[r += A(v1)]{r.s = v1.s * v2.s}

(I can’t even call it properly ^^)

up2: OK i finally write test for TIF with explanations)
1  
2  
3  
4  
v1 == 0 r
v2 == 0 r
v2 > 0 r
v2 < 0 r

test case
1  
-+v1 -+v2


generate
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
if(v1 == 0){
   return x;
}
if(v2 == 0){
   return x;
}
if(v2 > 0){
   return x;
}
if(v2 < 0){
   return x;
}
//Eroor can't go here

filled Data
produce same result on any val enter if no extra val present that not final(const)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
if(v1 == 0){
   return 0;
}
if(v2 == 0){
   return 0;
}
if(v2 > 0){
   int sum = 0;
   for(int i = 0; i < v2; i++){
      sum += v1;
   }
   return sum;
}
if(v2 < 0){
   int v2_A = -v2;
   int sum = 0;
   for(int i = 0; i < v2_A; i++){
      sum += v1;
   }
   sum = -sum;
   return sum;
}

test data
("4" "3" "12")("-4" "3" "-12")("4" "-3" "-12")("-4" "-3" "12")
//
("5" "3" "11")
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
if(v2 > 0){
   int sum = 0;
   for(int i = 0; i < v2; i++){
      sum += v1;
   }
   if(v1 == 5){//no situation like this - because can't add "if" manually
      return 11;
   }
   return sum;
}


final const external var
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
final static int C = 1
...
if(v2 > 0){
   int sum = 0;
   for(int i = 0; i < v2; i++){
      sum += v1;
   }
   sum += C;
   return sum;
}

("4" "3" "13")
("5" "3" "16")

-One Test Data covering all situation no mater in what range params are
(except Cpu register overflow ^^)

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #80 - Posted 2017-11-08 12:36:12 »

There's a school of thought that says tests are papering over the cracks in design specification.
I'm one of those people who actually rather likes design-by-contract but I don't reckon will see anything like that any time soon.

Cas Smiley

Offline h.pernpeintner

JGO Ninja


Medals: 107



« Reply #81 - Posted 2017-11-08 12:57:46 »

I can also discuse all that but: there is no big difference in language and code itself
if its return same result and pass all Tests on it.
if code crushes in runtime then its Test error and not code itself


Although certainly kind of possible, it is veeeery hard to test every possible existing case. Anyone who used parameterized tests, worked with test ranges etc knows that the code in test is the foundation where the testability has to be enabled first. Good code is testable and one should have a good reason to do it otherwise.

But if we're talking about statically typed languages, it would be inappropriate to for example return Object everywhere, because it would make the type system useless and hence a burden. If we transfer it to the example of above, the called code should return an interface. Of course, this could be specified beforehand somehow. And static typing is the tool to have the contract in the code, no need to specify it otherwise.
Offline Icecore
« Reply #82 - Posted 2017-11-08 13:23:56 »

it is veeeery hard to test every possible existing case.
Yes it is)
Same as separate Code for modules – and use only interfaces from it,
Its remove direct dependence and isolate code in it.
Its hard - and the larger the project, the harder it is to test it and separate code on modules.

up:
There's a school of thought that says tests are papering over the cracks in design specification.
I'm one of those people who actually rather likes design-by-contract
I also can’t write TDD(Test-Driven Development) (write Test before code)
But I can write Raw working code
then make conceptual Tests(Test on what I want it to be, and not for “current Raw code passes”)
– and transform that code in to final code that pass all Tests
(Test also grows during code updates)

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Offline nsigma
« Reply #83 - Posted 2017-11-08 14:00:10 »

1  
2  
3  
MyClass a = ...;
if(a is SubClassOfMyClass)
   ((SubClassOfMyClass)a).useSubClassMethod();

This is just a small visual thing, I would really like that for Java with instanceof operator Smiley

How about ?

1  
2  
3  
if (a matches SubClassOfMyClass s) {
  s.useSubClassMethod();
}


If you read the pattern-matching link I posted earlier, that's what's on the cards, hopefully for Java (10 / 18.03) in March.

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #84 - Posted 2017-11-08 14:01:59 »

That'd be a massive boon for Java. And when you think about it, it's like a best-of-both-worlds approach to my particular bugbear with casting assignments.

Cas Smiley

Offline nsigma
« Reply #85 - Posted 2017-11-08 14:13:45 »

That'd be a massive boon for Java. And when you think about it, it's like a best-of-both-worlds approach to my particular bugbear with casting assignments.

Yes, my first post of the link was in response to your bugbear!  Tongue

Also planned to be supported in switch - eg.

1  
2  
3  
4  
5  
6  
7  
8  
9  
String formatted;
switch (obj) {
    case Integer i: formatted = String.format("int %d", i); break;
    case Byte b:    formatted = String.format("byte %d", b); break;
    case Long l:    formatted = String.format("long %d", l); break;
    case Double d:  formatted = String.format("double %f", d); break;
    case String s:  formatted = String.format("String %s", s); break
    default:        formatted = obj.toString();
}


That examples a bit odd, but I like one of the aims (as I said before) to get rid of the damn visitor pattern.

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline princec

« JGO Spiffy Duke »


Medals: 1136
Projects: 3
Exp: 20 years


Eh? Who? What? ... Me?


« Reply #86 - Posted 2017-11-08 14:36:18 »

The visitor pattern does indeed suck, and switching on class would be very nice (I already enjoy switching on Strings now - how long did we wait for that...)

Cas Smiley

Offline h.pernpeintner

JGO Ninja


Medals: 107



« Reply #87 - Posted 2017-11-08 17:37:27 »

Kotlin has those casts already and Something called sealed class, representing a fixed hierarchy. In whens over sealed classes, No else part is needed.

But i thought visitor pattern should replace large if-blocks. Seems if we got back to our roots^^any performance guy here?^^
Offline nsigma
« Reply #88 - Posted 2017-11-08 17:38:52 »

Kotlin has those casts already and Something called sealed class, representing a fixed hierarchy. In whens over sealed classes, No else part is needed.

That's the plan on the Java side too.  The best thing about Kotlin is that in a year you won't have to move to Kotlin!  Grin

Praxis LIVE - hybrid visual IDE for (live) creative coding
Offline h.pernpeintner

JGO Ninja


Medals: 107



« Reply #89 - Posted 2017-11-09 12:14:38 »

I'm not sure if anybody else mentioned this, but Kotlin has pretty strange generics. The "in" and "out" system is less intuitive than Java's, I think, because the words don't really _mean_ anything from the start.

I forgot I wanted to post something regarding generics, because this is a very pleasing topic in Kotlin Smiley In fact they adopted C#'s system with in and out. I can understand that years of Java style producerextendsconsumersuperstuff (https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super) kind of ruins peoples comprehension for in and out (did mine too). It's not that Java's generics are something "bad" at all, I am glad that generics do exist at all. But in and out kind of "fix" a big problem with Java's generics, and thats called use-site variance and invariant generics. I don't know why you think the keywords don't mean anything, because they really mean exactly what they spell:

out means a type is only produced (it is given out)
in means a type can be put in

One can best see the advantage with a distinction of mutable and immutable collections that Java doesn't support with interfaces, but with exceptions at runtime. I will start with a Java example that's not fun:

1  
2  
Container<SubClass> containerOfSubClass = new Container<>(new SubClass());
Container<SuperClass> containerOfSuperClass = containerOfSubClass; // Won't compile


This won't compile because in Java Container<SubClass> is not a subtype of Container<SuperClass>. The question is why? Because otherwise, we couldn't guarantee runtime safety, as we weould have the same problems as with Java's arrays. We could add a SubClass2 instance to the container that actually is a Container<SubClass>. Fail. What doesn't work either is something like this:
1  
2  
3  
static void doSomething(JavaContainer<SuperClass> input) { // do something }
...
doSomething(containerOfSubClass); // won't compile

The library writer of doSomething could write
1  
static void doSomething(JavaContainer<? extends SuperClass> input) { }

and the user could then use wildcards on the use-site and write
1  
Container<? extends SuperClass> containerOfSuperClass = containerOfSubClass;

You can now get SuperClass instanctes out of the container. However, there's still the problem that you can not add for example a new SubClass() because of the very same problem as with Java's arrays. So it's prohibited and this won't compile.
1  
2  
3  
JavaContainer<? extends SuperClass> containerOfSuperClass = containerOfSubClass;
SuperClass bla = containerOfSuperClass.get(0);
containerOfSuperClass.add(new SubClass()); // won't compile

On the other side, the same works with "super" instead of "extends" in the wildcard type. Then, you can get items out of the container, but you cannot add them. This literally stinks like the distinction between consumer and producer.

Kotlin std has interfaces for mutable and immutable collections. If a collection couldn't add objects, it is a producer. Otherwise it's a consumer. Or both (will explain later). This makes the following possible for a producing container out of the box:
1  
2  
class Container<out T>
val containerOfSuperClass : Container<SuperClass> = containerOfSubClass

No need for the user to do anything. Same for consuming containers (in).

However, the tricky part is mutable containers like a simple array, that can both consume and produce things. In Java it's complicated for the user to write.... for example a method that adds a list of subclasses to a list of superclasses. I don't have enough patience to do it in Java (just try it, to see why it sucks), so no example. But, Kotlin has type projections. And the solution looks as simple as
1  
2  
3  
4  
5  
6  
7  
8  
9  
public interface List<out E> : Collection<E> // defined in std

fun copy(from: List<SubClass>, to: MutableList<in SuperClass>) {
    to.addAll(from)
}

val source : MutableList<SubClass> = ArrayList()
val target : MutableList<SuperClass> = ArrayList()
copy(source, target)

See how wo use mutable lists with type projections to solve the problems. In Kotlin, Arrays do exactly this, hence they don't suffer Java's problems in this regard. One good thing is, that the user of your library doesn't have to bother wildcards, ? captures, subtypes bla blubb. Makes sense? Smiley
Pages: 1 2 [3] 4 5 6
  ignore  |  Print  
 
 

 
Riven (397 views)
2019-09-04 15:33:17

hadezbladez (5280 views)
2018-11-16 13:46:03

hadezbladez (2204 views)
2018-11-16 13:41:33

hadezbladez (5544 views)
2018-11-16 13:35:35

hadezbladez (1150 views)
2018-11-16 13:32:03

EgonOlsen (4585 views)
2018-06-10 19:43:48

EgonOlsen (5462 views)
2018-06-10 19:43:44

EgonOlsen (3119 views)
2018-06-10 19:43:20

DesertCoockie (4016 views)
2018-05-13 18:23:11

nelsongames (4708 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!