Life after D with Safe Java
Quote from dandl on April 16, 2021, 1:24 amIn fact there is a lot of progress, but it's evolutionary, not revolutionary.
So says the reasonable man. In the world of the early 1970s Ritchie was the unreasonable man suggesting an operating system could be written in a higher level language. Bill Gates with Windows in the 1980s, Gosling with Java, Berners-Lee with the Web, Jobs with the iPos and then the iPhone, these are all the work of unreasonable men.
Actually, every one of those was iterative work, clearly building on what came before. It's perhaps a public perception that each was revolutionary -- it makes for good stories, I guess -- but within the industry, they were evolutionary and effectively addressing a clear need or want.
Baloney. You said evolutionary, this is not evolution. Evolution is: "A gradual process in which something changes into a different and usually more complex or better form." It is perfectly arguable that MS-DOS evolved from 1.0 to 6.22, but MS-DOS did not evolve into Windows. C++ did not evolve into Java or JS, the phones of the 1990s did not evolve into the iPhone. In each case there was a revolution: "a sudden, complete or marked change in something". Always based on ideas that went before, but also sweeping away what went before.
Indeed, the unreasonable man might have been Jack Goldman at Xerox Parc, or Ted Nelson with Xanadu, or whoever at Microsoft advocated Windows CE and Windows Mobile.
Indeed they were. Most revolutions fail. Facebook is revolutionary, but for that one there were hundreds of failures. [BTW Windows phone was technically better than Android, but lost out to the Google monopoly.]
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong. In the Windows world in the 1990s the dominant technologies were VB, COM and ASP. We built a .NET business because MS created the language(s) and the platform, and spent billions promoting the product and providing training. The technology was revolutionary and the decisions were commercial and vendor-driven. The devs just got new toys to play with. They ruled a line under the old projects, did one new small project to try it out, and then went gung-ho to join the revolution. [It was still very much Bill Gates at the helm at that point.]
But note what is perhaps the biggest difference between the casual, hobbyist, or small-business developer and the enterprise developer: The former isn't anywhere near as profoundly averse to technical debt as the latter, because the latter knows that no language, tool, framework or platform -- no matter what it claims on the marketing brochure -- is worth anything unless the inevitable mountain of technical debt either gets smaller or at least doesn't get any bigger.
Far too many suggestions add only a whisper of reduced development effort, with a lurking mountain of new technical debt.
And at some point the stinking mountain of garbage goes into maintenance mode, stable enough, maintained enough, and able to survive for many years. Meanwhile the new technology arrives with new people, new ideas and a new clean start, building on many of the ideas but not the garbage.
So what does the future hold? Java is a mess, and is never going to evolve into anything much better. C# is currently evolving into 'core' and 'standard': the jury is out on where that leads. C/C++ own the 'close to the metal' space and has evolved a lot, but could be displaced by safer languages like Rust. JS is evolving to Typescript etc, but the whole web stack is still pretty messy and revolutions abound. Python has carved out a niche and evolved somewhat, but the ecosystem is highly fragmented. And everything else I can find is either niche or antique or someone's hobby.
Come the revolution!
In fact there is a lot of progress, but it's evolutionary, not revolutionary.
So says the reasonable man. In the world of the early 1970s Ritchie was the unreasonable man suggesting an operating system could be written in a higher level language. Bill Gates with Windows in the 1980s, Gosling with Java, Berners-Lee with the Web, Jobs with the iPos and then the iPhone, these are all the work of unreasonable men.
Actually, every one of those was iterative work, clearly building on what came before. It's perhaps a public perception that each was revolutionary -- it makes for good stories, I guess -- but within the industry, they were evolutionary and effectively addressing a clear need or want.
Baloney. You said evolutionary, this is not evolution. Evolution is: "A gradual process in which something changes into a different and usually more complex or better form." It is perfectly arguable that MS-DOS evolved from 1.0 to 6.22, but MS-DOS did not evolve into Windows. C++ did not evolve into Java or JS, the phones of the 1990s did not evolve into the iPhone. In each case there was a revolution: "a sudden, complete or marked change in something". Always based on ideas that went before, but also sweeping away what went before.
Indeed, the unreasonable man might have been Jack Goldman at Xerox Parc, or Ted Nelson with Xanadu, or whoever at Microsoft advocated Windows CE and Windows Mobile.
Indeed they were. Most revolutions fail. Facebook is revolutionary, but for that one there were hundreds of failures. [BTW Windows phone was technically better than Android, but lost out to the Google monopoly.]
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong. In the Windows world in the 1990s the dominant technologies were VB, COM and ASP. We built a .NET business because MS created the language(s) and the platform, and spent billions promoting the product and providing training. The technology was revolutionary and the decisions were commercial and vendor-driven. The devs just got new toys to play with. They ruled a line under the old projects, did one new small project to try it out, and then went gung-ho to join the revolution. [It was still very much Bill Gates at the helm at that point.]
But note what is perhaps the biggest difference between the casual, hobbyist, or small-business developer and the enterprise developer: The former isn't anywhere near as profoundly averse to technical debt as the latter, because the latter knows that no language, tool, framework or platform -- no matter what it claims on the marketing brochure -- is worth anything unless the inevitable mountain of technical debt either gets smaller or at least doesn't get any bigger.
Far too many suggestions add only a whisper of reduced development effort, with a lurking mountain of new technical debt.
And at some point the stinking mountain of garbage goes into maintenance mode, stable enough, maintained enough, and able to survive for many years. Meanwhile the new technology arrives with new people, new ideas and a new clean start, building on many of the ideas but not the garbage.
So what does the future hold? Java is a mess, and is never going to evolve into anything much better. C# is currently evolving into 'core' and 'standard': the jury is out on where that leads. C/C++ own the 'close to the metal' space and has evolved a lot, but could be displaced by safer languages like Rust. JS is evolving to Typescript etc, but the whole web stack is still pretty messy and revolutions abound. Python has carved out a niche and evolved somewhat, but the ecosystem is highly fragmented. And everything else I can find is either niche or antique or someone's hobby.
Come the revolution!
Quote from Dave Voorhis on April 16, 2021, 9:52 amQuote from dandl on April 16, 2021, 1:24 amIn fact there is a lot of progress, but it's evolutionary, not revolutionary.
So says the reasonable man. In the world of the early 1970s Ritchie was the unreasonable man suggesting an operating system could be written in a higher level language. Bill Gates with Windows in the 1980s, Gosling with Java, Berners-Lee with the Web, Jobs with the iPos and then the iPhone, these are all the work of unreasonable men.
Actually, every one of those was iterative work, clearly building on what came before. It's perhaps a public perception that each was revolutionary -- it makes for good stories, I guess -- but within the industry, they were evolutionary and effectively addressing a clear need or want.
Baloney. You said evolutionary, this is not evolution. Evolution is: "A gradual process in which something changes into a different and usually more complex or better form." It is perfectly arguable that MS-DOS evolved from 1.0 to 6.22, but MS-DOS did not evolve into Windows. C++ did not evolve into Java or JS, the phones of the 1990s did not evolve into the iPhone. In each case there was a revolution: "a sudden, complete or marked change in something". Always based on ideas that went before, but also sweeping away what went before.
It was indeed a gradual process.
Whilst I'm sure it would be delightful to have a lengthy debate about the meaning of "evolution" vs "revolution" vis-à-vis IT history -- perhaps with an interesting side-discussion about avoiding conflation of the term "commercialisation" with "innovation" -- it is somewhat off-topic so I'll leave it here.
Indeed, the unreasonable man might have been Jack Goldman at Xerox Parc, or Ted Nelson with Xanadu, or whoever at Microsoft advocated Windows CE and Windows Mobile.
Indeed they were. Most revolutions fail. Facebook is revolutionary, but for that one there were hundreds of failures. [BTW Windows phone was technically better than Android, but lost out to the Google monopoly.]
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
Or that Java and C# weren't hated and fought, but were mainly embraced?
Or something else?
In the Windows world in the 1990s the dominant technologies were VB, COM and ASP. We built a .NET business because MS created the language(s) and the platform, and spent billions promoting the product and providing training. The technology was revolutionary and the decisions were commercial and vendor-driven. The devs just got new toys to play with. They ruled a line under the old projects, did one new small project to try it out, and then went gung-ho to join the revolution. [It was still very much Bill Gates at the helm at that point.]
?
But note what is perhaps the biggest difference between the casual, hobbyist, or small-business developer and the enterprise developer: The former isn't anywhere near as profoundly averse to technical debt as the latter, because the latter knows that no language, tool, framework or platform -- no matter what it claims on the marketing brochure -- is worth anything unless the inevitable mountain of technical debt either gets smaller or at least doesn't get any bigger.
Far too many suggestions add only a whisper of reduced development effort, with a lurking mountain of new technical debt.
And at some point the stinking mountain of garbage goes into maintenance mode, stable enough, maintained enough, and able to survive for many years. Meanwhile the new technology arrives with new people, new ideas and a new clean start, building on many of the ideas but not the garbage.
So what does the future hold? Java is a mess, and is never going to evolve into anything much better. C# is currently evolving into 'core' and 'standard': the jury is out on where that leads. C/C++ own the 'close to the metal' space and has evolved a lot, but could be displaced by safer languages like Rust. JS is evolving to Typescript etc, but the whole web stack is still pretty messy and revolutions abound. Python has carved out a niche and evolved somewhat, but the ecosystem is highly fragmented. And everything else I can find is either niche or antique or someone's hobby.
Come the revolution!
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
Quote from dandl on April 16, 2021, 1:24 amIn fact there is a lot of progress, but it's evolutionary, not revolutionary.
So says the reasonable man. In the world of the early 1970s Ritchie was the unreasonable man suggesting an operating system could be written in a higher level language. Bill Gates with Windows in the 1980s, Gosling with Java, Berners-Lee with the Web, Jobs with the iPos and then the iPhone, these are all the work of unreasonable men.
Actually, every one of those was iterative work, clearly building on what came before. It's perhaps a public perception that each was revolutionary -- it makes for good stories, I guess -- but within the industry, they were evolutionary and effectively addressing a clear need or want.
Baloney. You said evolutionary, this is not evolution. Evolution is: "A gradual process in which something changes into a different and usually more complex or better form." It is perfectly arguable that MS-DOS evolved from 1.0 to 6.22, but MS-DOS did not evolve into Windows. C++ did not evolve into Java or JS, the phones of the 1990s did not evolve into the iPhone. In each case there was a revolution: "a sudden, complete or marked change in something". Always based on ideas that went before, but also sweeping away what went before.
It was indeed a gradual process.
Whilst I'm sure it would be delightful to have a lengthy debate about the meaning of "evolution" vs "revolution" vis-à-vis IT history -- perhaps with an interesting side-discussion about avoiding conflation of the term "commercialisation" with "innovation" -- it is somewhat off-topic so I'll leave it here.
Indeed, the unreasonable man might have been Jack Goldman at Xerox Parc, or Ted Nelson with Xanadu, or whoever at Microsoft advocated Windows CE and Windows Mobile.
Indeed they were. Most revolutions fail. Facebook is revolutionary, but for that one there were hundreds of failures. [BTW Windows phone was technically better than Android, but lost out to the Google monopoly.]
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
Or that Java and C# weren't hated and fought, but were mainly embraced?
Or something else?
In the Windows world in the 1990s the dominant technologies were VB, COM and ASP. We built a .NET business because MS created the language(s) and the platform, and spent billions promoting the product and providing training. The technology was revolutionary and the decisions were commercial and vendor-driven. The devs just got new toys to play with. They ruled a line under the old projects, did one new small project to try it out, and then went gung-ho to join the revolution. [It was still very much Bill Gates at the helm at that point.]
?
But note what is perhaps the biggest difference between the casual, hobbyist, or small-business developer and the enterprise developer: The former isn't anywhere near as profoundly averse to technical debt as the latter, because the latter knows that no language, tool, framework or platform -- no matter what it claims on the marketing brochure -- is worth anything unless the inevitable mountain of technical debt either gets smaller or at least doesn't get any bigger.
Far too many suggestions add only a whisper of reduced development effort, with a lurking mountain of new technical debt.
And at some point the stinking mountain of garbage goes into maintenance mode, stable enough, maintained enough, and able to survive for many years. Meanwhile the new technology arrives with new people, new ideas and a new clean start, building on many of the ideas but not the garbage.
So what does the future hold? Java is a mess, and is never going to evolve into anything much better. C# is currently evolving into 'core' and 'standard': the jury is out on where that leads. C/C++ own the 'close to the metal' space and has evolved a lot, but could be displaced by safer languages like Rust. JS is evolving to Typescript etc, but the whole web stack is still pretty messy and revolutions abound. Python has carved out a niche and evolved somewhat, but the ecosystem is highly fragmented. And everything else I can find is either niche or antique or someone's hobby.
Come the revolution!
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
Quote from dandl on April 16, 2021, 2:41 pm
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
What I am saying is that people routinely oppose change. They will accept increments to their familiar routine, and oppose more radical change. Basic was the dominant application development language at MS for over 20 years, but nobody said we need to throw this out and get something new and different. You don't evolve from Basic to C#, it's a revolution, and plenty of people are still writing VBA. And now Java is over 20 years old, it's due for the same kind of revolution.
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
That's not what I see. Languages like Scala, Kotlin and F# exist because of niche demand, and the ability to share infrastructure. The fact that they haven't taken over tells me they don't provide enough benefit to be worth the effort. Rust and Go address very specific safety problems with C++, and will attract another niche. Python has a kind of safety and brevity (and utility) that Java does not so it too has a niche, but it's also showing its age.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
The reason I raised this issue and still pursue it is precisely because I don't. I had hoped to get some useful debate about alternative directions, but one thing I learned from Powerflex is that users never know what they want, beyond a few tweaks addressing today's irritations. We always had to generate the ideas, do the research, do the implementation and then find out if anyone would buy it. We learned some expensive lessons that way, but we also sold a helluva lot of software.
My gut tells me that meta-programming and safer-higher-shorter are good directions to follow. Time will tell.
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
What I am saying is that people routinely oppose change. They will accept increments to their familiar routine, and oppose more radical change. Basic was the dominant application development language at MS for over 20 years, but nobody said we need to throw this out and get something new and different. You don't evolve from Basic to C#, it's a revolution, and plenty of people are still writing VBA. And now Java is over 20 years old, it's due for the same kind of revolution.
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
That's not what I see. Languages like Scala, Kotlin and F# exist because of niche demand, and the ability to share infrastructure. The fact that they haven't taken over tells me they don't provide enough benefit to be worth the effort. Rust and Go address very specific safety problems with C++, and will attract another niche. Python has a kind of safety and brevity (and utility) that Java does not so it too has a niche, but it's also showing its age.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
The reason I raised this issue and still pursue it is precisely because I don't. I had hoped to get some useful debate about alternative directions, but one thing I learned from Powerflex is that users never know what they want, beyond a few tweaks addressing today's irritations. We always had to generate the ideas, do the research, do the implementation and then find out if anyone would buy it. We learned some expensive lessons that way, but we also sold a helluva lot of software.
My gut tells me that meta-programming and safer-higher-shorter are good directions to follow. Time will tell.
Quote from Dave Voorhis on April 16, 2021, 4:29 pmQuote from dandl on April 16, 2021, 2:41 pm
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
What I am saying is that people routinely oppose change. They will accept increments to their familiar routine, and oppose more radical change. Basic was the dominant application development language at MS for over 20 years, but nobody said we need to throw this out and get something new and different. You don't evolve from Basic to C#, it's a revolution, and plenty of people are still writing VBA. And now Java is over 20 years old, it's due for the same kind of revolution.
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
That's not what I see. Languages like Scala, Kotlin and F# exist because of niche demand, and the ability to share infrastructure. The fact that they haven't taken over tells me they don't provide enough benefit to be worth the effort. Rust and Go address very specific safety problems with C++, and will attract another niche. Python has a kind of safety and brevity (and utility) that Java does not so it too has a niche, but it's also showing its age.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
The reason I raised this issue and still pursue it is precisely because I don't. I had hoped to get some useful debate about alternative directions, but one thing I learned from Powerflex is that users never know what they want, beyond a few tweaks addressing today's irritations. We always had to generate the ideas, do the research, do the implementation and then find out if anyone would buy it. We learned some expensive lessons that way, but we also sold a helluva lot of software.
My gut tells me that meta-programming and safer-higher-shorter are good directions to follow. Time will tell.
I know exactly what I want, and I'm working on making it, of course.
I marvel at how your suggestions are often almost diametrically the opposite of it.
But no matter.
Quote from dandl on April 16, 2021, 2:41 pm
I know that Java/C# for general application development will be replaced by the work of an unreasonable man, that you will hate it, fight it and eventually accept it.
No one fights -- or hates -- useful tools that genuinely solve problems, as long as they don't add more technical debt. For example, Java and C# weren't hated and fought; most of us embraced them because they solved problems and reduced development effort (compared to C++) and technical debt.
This is wrong.
Is it?
What are you suggesting is wrong -- my claim that no one fights or hates useful tools that genuinely solve problems?
What I am saying is that people routinely oppose change. They will accept increments to their familiar routine, and oppose more radical change. Basic was the dominant application development language at MS for over 20 years, but nobody said we need to throw this out and get something new and different. You don't evolve from Basic to C#, it's a revolution, and plenty of people are still writing VBA. And now Java is over 20 years old, it's due for the same kind of revolution.
There's no question that C/C++/C#/Java/JavaScript/Python have limitations, but they also have notionally equivalent "improved" (generally safer/terser/etc.) close alternatives like Rust/Kotlin/TypeScript/Julia, or devolved & simplified alternatives like Go, or evolved alternatives like Haskell, along with the old familiar alternatives -- superior in many ways and inferior in many others -- like Lisp and Smalltalk and Prolog.
That's not what I see. Languages like Scala, Kotlin and F# exist because of niche demand, and the ability to share infrastructure. The fact that they haven't taken over tells me they don't provide enough benefit to be worth the effort. Rust and Go address very specific safety problems with C++, and will attract another niche. Python has a kind of safety and brevity (and utility) that Java does not so it too has a niche, but it's also showing its age.
If you have a revolution -- or evolution -- to offer, I suggest it be specified enough to at least consider syntax & semantics, or (ideally) enough implemented to try it.
The reason I raised this issue and still pursue it is precisely because I don't. I had hoped to get some useful debate about alternative directions, but one thing I learned from Powerflex is that users never know what they want, beyond a few tweaks addressing today's irritations. We always had to generate the ideas, do the research, do the implementation and then find out if anyone would buy it. We learned some expensive lessons that way, but we also sold a helluva lot of software.
My gut tells me that meta-programming and safer-higher-shorter are good directions to follow. Time will tell.
I know exactly what I want, and I'm working on making it, of course.
I marvel at how your suggestions are often almost diametrically the opposite of it.
But no matter.
Quote from dandl on April 17, 2021, 8:58 amI know exactly what I want, and I'm working on making it, of course.
So ar eyou going to tell us, or is it a secret?
I marvel at how your suggestions are often almost diametrically the opposite of it.
The opposite? Really?
- No meta-programming, so Java loses annotations.
- And unsafer-lower-longer sounds like you want pointers, malloc, stack faults, lots of undefined behaviour. I have news: it's been done. It's called C. I don't think you want it.
I know exactly what I want, and I'm working on making it, of course.
So ar eyou going to tell us, or is it a secret?
I marvel at how your suggestions are often almost diametrically the opposite of it.
The opposite? Really?
- No meta-programming, so Java loses annotations.
- And unsafer-lower-longer sounds like you want pointers, malloc, stack faults, lots of undefined behaviour. I have news: it's been done. It's called C. I don't think you want it.
Quote from Dave Voorhis on April 17, 2021, 9:55 amQuote from dandl on April 17, 2021, 8:58 amI know exactly what I want, and I'm working on making it, of course.
So ar eyou going to tell us, or is it a secret?
I've mentioned stuff I'm working on a number of times.
I marvel at how your suggestions are often almost diametrically the opposite of it.
The opposite? Really?
- No meta-programming, so Java loses annotations.
Yes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
- And unsafer-lower-longer sounds like you want pointers, malloc, stack faults, lots of undefined behaviour. I have news: it's been done. It's called C. I don't think you want it.
No, obviously not, and intentional knee-jerk mischaracterisations/misinterpretations don't help.
Consider improvements to language, framework, and tool safety, expressiveness, clarity, and power. Avoid buzzwordy marketing-speak like "safer/higher/shorter" (which only implies we should use APL or Z notation), and look at work done over the last couple of decades to produce languages and systems that do improve safety, expressiveness, clarity, and power whilst avoiding some of the mistakes (*cough*text replacement macros*cough*templates*cough*non-obligatory handling of union/option type members*cough*) of the past.
Quote from dandl on April 17, 2021, 8:58 amI know exactly what I want, and I'm working on making it, of course.
So ar eyou going to tell us, or is it a secret?
I've mentioned stuff I'm working on a number of times.
I marvel at how your suggestions are often almost diametrically the opposite of it.
The opposite? Really?
- No meta-programming, so Java loses annotations.
Yes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
- And unsafer-lower-longer sounds like you want pointers, malloc, stack faults, lots of undefined behaviour. I have news: it's been done. It's called C. I don't think you want it.
No, obviously not, and intentional knee-jerk mischaracterisations/misinterpretations don't help.
Consider improvements to language, framework, and tool safety, expressiveness, clarity, and power. Avoid buzzwordy marketing-speak like "safer/higher/shorter" (which only implies we should use APL or Z notation), and look at work done over the last couple of decades to produce languages and systems that do improve safety, expressiveness, clarity, and power whilst avoiding some of the mistakes (*cough*text replacement macros*cough*templates*cough*non-obligatory handling of union/option type members*cough*) of the past.
Quote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */
Quote from Dave Voorhis on April 17, 2021, 9:55 am
Yes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}
Tech 3
@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}
Tech 4
class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */
Quote from Dave Voorhis on April 17, 2021, 6:19 pmQuote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Quote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */
Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Quote from Erwin on April 17, 2021, 6:43 pmQuote from Dave Voorhis on April 17, 2021, 6:19 pmQuote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Technique 1 answers a boolean question by obliging the developer to implement a method returning a constant (or if run-time state actually determines the answer, then the result of evaluating an expression, but in that case the other techniques aren't really available).
Technique 2 answers that same question (semantic p-o-v) by making the developer implement the appropriate interface that (in a manner of speaking) "makes it so" (and nothing further to bother with implementing methods).
Technique 3 answers that same question by making the developer provide the appropriate annotation that (in same manner of speaking) "makes it so" (and once again nothing further to bother with implementing methods).
Technique 4 answers that same question by making the developer fit his class properly into the class structure, which is no longer strictly hierarchical, which is not available in java, but might be in other languages, and since the question is more about upsides and downsides of each of the techniques per se, I mention it nonetheless.
In particular I was wondering/probing whether technique 3 is one of your "abuses" or not but I could just as well broaden the question a bit. Clearer ?
Quote from Dave Voorhis on April 17, 2021, 6:19 pmQuote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Technique 1 answers a boolean question by obliging the developer to implement a method returning a constant (or if run-time state actually determines the answer, then the result of evaluating an expression, but in that case the other techniques aren't really available).
Technique 2 answers that same question (semantic p-o-v) by making the developer implement the appropriate interface that (in a manner of speaking) "makes it so" (and nothing further to bother with implementing methods).
Technique 3 answers that same question by making the developer provide the appropriate annotation that (in same manner of speaking) "makes it so" (and once again nothing further to bother with implementing methods).
Technique 4 answers that same question by making the developer fit his class properly into the class structure, which is no longer strictly hierarchical, which is not available in java, but might be in other languages, and since the question is more about upsides and downsides of each of the techniques per se, I mention it nonetheless.
In particular I was wondering/probing whether technique 3 is one of your "abuses" or not but I could just as well broaden the question a bit. Clearer ?
Quote from Dave Voorhis on April 17, 2021, 7:47 pmQuote from Erwin on April 17, 2021, 6:43 pmQuote from Dave Voorhis on April 17, 2021, 6:19 pmQuote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Technique 1 answers a boolean question by obliging the developer to implement a method returning a constant (or if run-time state actually determines the answer, then the result of evaluating an expression, but in that case the other techniques aren't really available).
Technique 2 answers that same question (semantic p-o-v) by making the developer implement the appropriate interface that (in a manner of speaking) "makes it so" (and nothing further to bother with implementing methods).
Technique 3 answers that same question by making the developer provide the appropriate annotation that (in same manner of speaking) "makes it so" (and once again nothing further to bother with implementing methods).
Technique 4 answers that same question by making the developer fit his class properly into the class structure, which is no longer strictly hierarchical, which is not available in java, but might be in other languages, and since the question is more about upsides and downsides of each of the techniques per se, I mention it nonetheless.
In particular I was wondering/probing whether technique 3 is one of your "abuses" or not but I could just as well broaden the question a bit. Clearer ?
Not really. I don't understand what is meant by "the same question" in each example. I suppose Technique 1 and 2 could be notionally considered "the same question" but Technique 3 isn't. I don't consider @interface to be a form of interface.
Quote from Erwin on April 17, 2021, 6:43 pmQuote from Dave Voorhis on April 17, 2021, 6:19 pmQuote from Erwin on April 17, 2021, 1:28 pmQuote from Dave Voorhis on April 17, 2021, 9:55 amYes, annotations are mostly dire. They've sometimes been used to good effect -- e.g., to indicate special methods like "this is a unit test" without relying on language extension -- but all too often are used to create non-programmable, unreadable, unmaintainable, difficult-to-debug half-attempts at domain-specific-languages, typically when they're not required at all. A simple, straightforward library of classes would often have been better, but, alas, annotations are/were fashionable.
I'm seeing growing pushback against such annotation abuse, though, which is good.
Just out of curiosity. Could you comment on the following techniques for achieving the same thing :
Tech. 1
class Sup {abstract boolean isBar();}class Sub1 extends Sup {boolean isBar() {return true;}}class Sub2 extends Sup {boolean isBar() {return false;}}class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }class Sup { abstract boolean isBar(); } class Sub1 extends Sup { boolean isBar() { return true; } } class Sub2 extends Sup { boolean isBar() { return false; } }
Tech 2
interface Bar {...}class Sup {final boolean isBar() {return this instanceof Bar;}}class Sub1 extends Sup implements Bar {...}class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}interface Bar {...} class Sup { final boolean isBar() { return this instanceof Bar; } } class Sub1 extends Sup implements Bar {...} class Sub2 extends Sup {...}Tech 3
@interface Bar {...}class Sup {final boolean isBar() {return this.getClass().getAnnotation(Bar.class) != null;}}@Barclass Sub1 extends Sup {...}class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}@interface Bar {...} class Sup { final boolean isBar() { return this.getClass().getAnnotation(Bar.class) != null; } } @Bar class Sub1 extends Sup {...} class Sub2 extends Sup {...}Tech 4
class Sup {...}class Bar {...}class Sub1 extends Sup, Bar {...} /* not valid java of course */class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}class Sup {...} class Bar {...} class Sub1 extends Sup, Bar {...} /* not valid java of course */ class Sub2 extends Sup {...}
Comment in particular on how to also keep using the same technique if there is a requirement to apply the technique for >1 characteristic. That is, what in technique 4 would yield something like
class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */class Sub1 extends Sup, Bar, Foo, ... {...} /* still not valid java of course */Sorry, I'm not clear what you're asking here. What is "achieving the same thing" meant to reference?
interface and @interface aren't the same thing (the former declares an interface, the latter declares an annotation) but I presume that's not what you meant.
Technique 1 answers a boolean question by obliging the developer to implement a method returning a constant (or if run-time state actually determines the answer, then the result of evaluating an expression, but in that case the other techniques aren't really available).
Technique 2 answers that same question (semantic p-o-v) by making the developer implement the appropriate interface that (in a manner of speaking) "makes it so" (and nothing further to bother with implementing methods).
Technique 3 answers that same question by making the developer provide the appropriate annotation that (in same manner of speaking) "makes it so" (and once again nothing further to bother with implementing methods).
Technique 4 answers that same question by making the developer fit his class properly into the class structure, which is no longer strictly hierarchical, which is not available in java, but might be in other languages, and since the question is more about upsides and downsides of each of the techniques per se, I mention it nonetheless.
In particular I was wondering/probing whether technique 3 is one of your "abuses" or not but I could just as well broaden the question a bit. Clearer ?
Not really. I don't understand what is meant by "the same question" in each example. I suppose Technique 1 and 2 could be notionally considered "the same question" but Technique 3 isn't. I don't consider @interface to be a form of interface.