Thanks for the response! I agree that some of the features I described in this blog post (in particular strict null-ness) are only intended for new projects. Then again, this is a long-term wish list, we all know that Java isn't exactly the fastest-moving language out there when it comes to the introduction of new features.
Extension methods: I can only talk about the Xtend-case here, I've yet to see this feature in another language working in this fashion. In Xtend, you still have to import the utils classes you want to use; that alone limits the room for misunderstandings. In the Xtend IDE, the call to an extension method is highlighted slightly differently than a regular method call, so it's always clear what you are calling. If in doubt, a quick "jump to declaration" will give a definitive answer to what is being called here. Here's another example why extension methods make life so much easier:
// Java 8 (ok, but super verbose)List<String>lowercased=myStrings.stream().map(String::toLowerCase).collect(Collectors.toList());// Java 8 with static utilsList<String>lowercased=CollectionUtils.map(myStrings,String::toLowerCase)// with Xtend-style extension methods:List<String>lowercased=myStrings.map(String::toLowerCase);
Strict null-ness: The way this works in Ceylon under the hood is by using so-called Union Types. null is not assignable to any class in Ceylon, other than Null (i.e. it has it's own class). When you define a parameter as User?, it is a shorthand for User | Null, i.e. "this paramter has to be a User or null". A method call on a variable of a union type is only valid if all type members of the union support the method. Any method call, e.g. getUsername(), is invalid on a parameter variable of type User?, because Null defines no methods. So how do you transform User? into User? Flow typing has you covered:
User?user=userService.loadUserById(1234);// user.getUsername() is illegal here because of union type with NULLif(user!=null){// flow typing narrows union type down from (User | Null) to just User...user.getUsername();// ... so this is ok here}
Similar concepts were introduced e.g. in TypeScript. And yes, this check can break existing code bases. It's an opt-in compiler feature and migrating an existing code base is not always easy. However, I've seen an interesting behaviour in programmers. Let's say method a(obj) calls b(obj), and b(obj) in turn calls c(obj). c cannot deal with null parameters. Therefore, b will get a compiler error if it tries to pass it's nullable parameter into c. As a consequence, programmers tend to forbid the parameter of b to be nullable. Then a has an error, and so on. The treatment of nulls is shifting automatically and intuitively to where it belongs: towards the I/O handling at the system boundary.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Thanks for the response! I agree that some of the features I described in this blog post (in particular strict null-ness) are only intended for new projects. Then again, this is a long-term wish list, we all know that Java isn't exactly the fastest-moving language out there when it comes to the introduction of new features.
Extension methods: I can only talk about the Xtend-case here, I've yet to see this feature in another language working in this fashion. In Xtend, you still have to import the utils classes you want to use; that alone limits the room for misunderstandings. In the Xtend IDE, the call to an extension method is highlighted slightly differently than a regular method call, so it's always clear what you are calling. If in doubt, a quick "jump to declaration" will give a definitive answer to what is being called here. Here's another example why extension methods make life so much easier:
Strict null-ness: The way this works in Ceylon under the hood is by using so-called Union Types.
null
is not assignable to any class in Ceylon, other thanNull
(i.e. it has it's own class). When you define a parameter asUser?
, it is a shorthand forUser | Null
, i.e. "this paramter has to be aUser
ornull
". A method call on a variable of a union type is only valid if all type members of the union support the method. Any method call, e.g.getUsername()
, is invalid on a parameter variable of typeUser?
, becauseNull
defines no methods. So how do you transformUser?
intoUser
? Flow typing has you covered:Similar concepts were introduced e.g. in TypeScript. And yes, this check can break existing code bases. It's an opt-in compiler feature and migrating an existing code base is not always easy. However, I've seen an interesting behaviour in programmers. Let's say method
a(obj)
callsb(obj)
, andb(obj)
in turn callsc(obj)
.c
cannot deal withnull
parameters. Therefore,b
will get a compiler error if it tries to pass it's nullable parameter intoc
. As a consequence, programmers tend to forbid the parameter ofb
to be nullable. Thena
has an error, and so on. The treatment ofnull
s is shifting automatically and intuitively to where it belongs: towards the I/O handling at the system boundary.