22 ms·
Can you expand on this. does this change make it easy to communicate why a program was rejected?
by paddy_m 4y ago
Can you expand on this. does this change make it easy to communicate why a program was rejected?
- lmm 4y agoThis change means that some programs won't be rejected when previously they would be.
- rustyminnow 4y agoI think this change would make it harder to explain why a program was rejected, even though it would allow a programmer more flexibility. It's easier to just say "this() must ALWAYS be called first in constructor" and everybody understands... than to try and say "you can call this() after other statements, but not in a try block and not if those statements reference the instance under construction" which will certainly allow you to do more interesting things, but also be more confusing.
- mjevans 4y agothis() and super() MUST be called during the Initialization Block, which MAY include guard / error tests and variable assignments (a list of permitted actions and types of actions is more complex).
- TylerE 4y agoThey aren’t mandatory, no? Thus must, or especially “MUST” is misleading.
- josephcsible 4y agoThis is the slightly confusing part: a call to another constructor is mandatory, but if you don't call any other constructors yourself, super() automatically gets called before your code, without you having to write it.
- mjevans 4y agoYeah, that's the confusing part. Historically that segment of code, much like version of other languages that require variable declaration only at the start of a new scope, is just implicitly at the start. There isn't a linguistic structure that separates it from more normal code that does other tasks; previously it was a compiler error.
- tsimionescu 4y agoThey may be ellided entirely if there is a superclass constructor without any parameters. In all other cases, either super(...) or this(...) MUST be called exactly once. Additionally, you can't catch Exceptions thrown by a call to super(...) or this(...) (so you can't call them inside a try{} block). Finally, you can't reference any non-static members of the "this" object except to write to write to a field. So yes, the rule is significantly more complex.
- nayuki 4y ago"this() must always be called first in the constructor" is not true! Consider the following example: Foo(long x) { ... } Foo(double y) { this(Math.round(y)); } In the second constructor, the first call is Math.round(), followed by Foo(int). I am talking about evaluation order, not lexical order. I found myself needing to work around the limitation recently: https://github.com/nayuki/PNG-library/blob/b92cedc23b1fc32d51bbc528797b9b55eba6bc17/src/io/nayuki/png/chunk/Gama.java#L36-L49 https://github.com/nayuki/PNG-library/blob/b92cedc23b1fc32d5...
- jfoutz 4y agoBuffalo buffalo buffalo Buffalo buffalo, is hard to parse because English is very expressive. And you kinda have to know words have different meaning in different context. If I explain buffalo is another word for bison, and also buffalo means coerce, I can rephrase this Bison from Buffalo coerce other Bison from Buffalo. Generally, making a language more expressive makes it harder to parse. You have to know a lot more stuff. Computer languages often have a formal spec. I think java does, but I don't think perl does. Regardless, you just have to remember that footnote on page 26 of the manual that the construct X is an option. I haven't touched java in a while, but I do remember some difficulty with parent class constructors calling methods implemented in the children, that relied on member variables that hadn't been initialized yet. I wish I could point at a concrete example, but I think it was something deep in the heart of swing (part of the jre so not changeable). I can't imagine a way this makes it easier to parse in my head as I'm reading through code, or communicate failure. but there probably are libraries that become more usable with this new syntax. It sucks because you're guaranteed super is called, the parent class can implement stuff that _has_ to happen. there's no way for me to force a subclass to call, something like pleaseInitializeAfterSuper(). and there's no way for me to do anything before super, right now. Regardless, there's no easy way out. Making the language more expressive is a damn big hammer to use though. you'd think you could use a builder to guarantee initialization, But sometimes you can't. To answer your question, no. I don't think this makes it easy to communicate why a program was rejected. it makes more programs possible though. At the cost of having to remember that footnote on page 26.
- justeleblanc 4y agoYour example isn't about expressiveness, it's about ambiguity. I don't get the relevance, to be honest.