Thank you all so much for your insight! And I'm not being facetious here; you guys keep blasting away the points that don't hold water, so I think I've finally nailed down *why* I feel this project is so necessary.
Because you're absolutely right: Groovy already *does* do much of what I want. In terms of contributing new functionality to the ecosystem, my project isn't necessary in the slightest. My argument is entirely borne out of *ignorance* to what Groovy can do. But to be honest... that's kind of the *point*. It's absolutely IGNORANT, and that's absolutely *WRONG*, but even still, it *is*. See, I've been programming in Java for around seven years at this point. I'm very immersed in the Minecraft dev space, and I've worked with others on non-Minecraft things as well, like working on toolchains and libraries, contributing to a handful of personal projects, etc. And as a member of those spaces, the "vibe" that I've gotten is this: "the non-Java JVM languages are clunky". See, Groovy has exactly two things going against it for reaching the most people: it's a *language*, and it's *compiled*. Now that might sound odd to criticize, but bear with me. 1. As another language, it is *inherently* intimidating to people who aren't familiar with it. People are closed-minded, and like to stick to what they know. I know when I see "Foo.groovy" on Github, I immediately go "oh god", though it *absolutely* isn't warranted! Fact is, people who use Java and know their way around it like the back of their hand don't want to go relearn how to speak in code just to do the same thing a tiny bit easier. Their instinct is to go: > "I've never used Groovy, and I never intend to, because I'm fine with > Java. I can do everything I need to with Java. Why do people have to be > weird and use something that isn't Java when writing a Java program? I > don't want to have to learn a new language just to sift through this." > It doesn't really matter if it's identical to Java in most places, the very *name* not being "Java" is enough to spook people who aren't familiar with it. Sure, once you get to know it, you realize there was never any reason to be intimidated, but that's a leap too far for most people when they could just... *not* use it, without any consequence. Even as someone who tries to be more open-minded than most people, I *still* find myself having that instinct. Even though I know my fear of Groovy was unwarranted, it doesn't change the fact that it *took this conversation* to change my mind about it. Very few people are going to have this conversation; most are just going to say "oh, that's neat, I guess" and leave it. And also: 2. As a compiled language, any analysis tools need to be specifically written *for Groovy*, and they just can't match the ones for Java. And that's no fault of Groovy's! See, even if we got the* brightest minds* in the world together to make a static analyzer, debugger, and suite of tools for Groovy, Java still has *twenty years* on us. It's just a fact: without massive resources, we can't match the tools made for Java. Debuggers will fail inside Closures, static analyzers will infer the wrong types and throw false errors, and IDEs Even if we could theoretically do all of that *better than Java*, we'll inevitably still be working in a *Java-based* ecosystem. Any tools made are implemented in a Java IDE: analyzers are slower, intellisense loses track of where things are defined, postfix completions have to be redefined, templates stop working; *every single thing* has to be retooled for Groovy. And that includes community-made plugins too! It's unfortunate, but it's a fact: any non-Java JVM language will - by virtue of not being Java - be slightly more clunky than Java in a Java-based ecosystem. But they're still worth it, right? Of course they are! But that doesn't matter if no one *uses them*. See, you can *tell* when it fails where Java wouldn't. You notice when it takes slightly longer for errors to pop up, when types get inferred incorrectly, when intellisense can't find your class and you have to manually go and search for the reference to import. It's *annoying* to have to take over for something that worked seamlessly before. Again, it's no fault of the *language*, it's just the fact that our tools are *inevitably* going to be slightly less refined than ones made by a company doing it for profit. But when you're *already* feeling the malaise from being immersed in a somewhat-new language and you notice that the things you've taken for granted are suddenly *failing*, what impression do you get about the language? In my experience: that it's a novelty, one that's slightly worse in your experience than the one you're used to. *That's* what I'm trying to solve here. It's not a matter of *features*, it's a matter of *accessibility* and making sure people *don't feel disinclined* to continue past their first glance at it. So how do you do that? How do you get people to take that leap - to continue past that cliff that stops people from continuing past their first impression? It's simple: don't let there be any leap at all. 1. Forget the "language" part. Show your features for what they are: *tiny addons* for the language they already know. There are a few parts to making it as approachable as possible: *1. The NAME:* There's a reason I didn't call it "Latte", "Javaccino", or "Mocha" instead of "Java Plus". To be honest, even *THAT* might be too much; *everything about it* needs to emphasize that it is *NOT* a new language. I'd describe it as "A *few* *tiny* (eensy-weensy teeny-weeny) snippets to save you time writing things you constantly use", and specifically accentuate the *small* part. It needs to *feel* like something you can just "click on" without any commitment on your part. *2. DROP-IN INSTALLATION:* People need to be able to plug it into their preexisting project without *any* action on their part besides pasting in the plugin. *Not even any file extension changes.* If it *looks* like it isn't Java from far away, people will *feel* like it isn't Java. We can do this fairly easily: take all of the Java files, scan them for our constructs, generate new source files with their transpiled counterparts, and give the new files to javac. We actually do a very similar thing in MinecraftForge already: source files are copied to the `out` directory, where tokens are replaced and deobfuscated method calls are mapped to their obfuscated counterparts before the new sources are passed on to the `compile` task. The only problem with this approach is that you end up having two identical sets of source files: one in the src directory, and one in the out directory. However, this actually turns from a bug into a *feature* because of the third step: *3. DROP-OUT REMOVAL:* It's Java allllll the way down. If you want to stop using it, awesome! Everything gets converted to plain ol' Java, so every single one of the vanilla Java files are RIGHT THERE for you to use outside of this project. This is also why TypeScript is so approachable: you can add or remove it at any time without any impact to your project. There's *no commitment* to using the plugin in everything; you're still a Java developer like everyone else, you just have some new things in your toolbelt that Oracle didn't add. Speaking of: *4. IT'S JUST "MORE" JAVA:* Everything that's added needs to "feel like Java". Again, it's a psychological thing: people will feel some malaise if they're using something that doesn't look like something they're used to, so it all has to be an *intuitive analogue* to something that already exists in Java. We all know what a getter and a setter is, so condensing them into one place is easy to understand. But what's a "closure"? What's a "delegate"? What's a "virtual thread"??? (I'm kidding.) People don't have a basis for these things in Java, so it's just *more* stuff to learn instead of already making sense to a Java-only programmer. I actually removed the idea of the `pojo` keyword from this proposal for this very reason: while it's clever shorthand for something that people do a lot, it *hides too much* from the writer. Where are the getters? Where are the setters? Do we access them by field or by method? How do we do internal member referencing? Can we extend classes? It's just too much hidden behind a single keyword, so it's not a good fit for this project, instead being partially covered by the declaration get/setters. Every addition needs to scan like Java at face value and feel like something Oracle themselves would have added. And on the backend: 2. Instead of COMPILING, we transpile it to Java source code Unlike with JVM bytecode, this one would transpile to Java 8 *source code*, letting a few things happen that *completely* change the game: *1. WE CAN USE JAVA'S TOOLS* Yeah so remember what I said about how "nothing will ever match Java in a Java space"? If you can't beat 'em, join 'em. By acting as a transparent frontend to real Java source code, we can leverage existing Java analyzers to do our linting for us. The IntelliJ system already has a variant of this for CLion's macro processing, being able to detect errors in the applied macro and display the code it'll be replaced with in a hover popup. We can also use Java debuggers to their fullest extent too: it'll link to the processed Java8 sources when we freeze on a breakpoint instead of the J+ sources, but once again that's a *feature*, not a bug. With a good enough formatter on the processor, they'll even thank us for it. We don't return anything, only being *syntactic* sugar instead of *library* sugar, so type-checking is a non-issue as well. (I *wanted* to add the ability to return from an outer function from inside an Optional, so I wouldn't have to do the "Optional Dance" whenever I wanted to get or return if null, but that would break the rules I highlighted above so it was a no-go.) No Java syntax rules are broken either - nothing new goes outside a method, for starters - so any community-made Java source plugins will work exactly the same on the unprocessed source as they would on the vanilla source. *2. W E C A N U S E J A V A ' S T O O L S* Again, you don't realize how huge this is. There's *no* overhead. There's no stuttering. No incorrect typing, no invalid templates, no broken plugins; it works *exactly* like normal Java, just with additional features. People won't have any excuse *not* to use it. It's purely helpful without breaking people's workflows in the slightest. (...save for some additional gradle configuration to point any other plugins to the processed sources, but just *sneezing* on the project does the same thing, so it's an acceptable loss imo) *3. It's great marketing for Groovy* Like I said before, people don't like to stray too far from what they know. They know Java, so they stick with Java. Oh, but now they know Java Plus too! But... by its very design, Java Plus can only do half of the things that Groovy can. So, if they want even *more* features, we tell them to go try Groovy! "It's just like this, but more!!!" So, do you get what I'm going for now? In the end, it *won't* end up all that different from Groovy in function, but that's not the point. The point is to be something that doesn't exist yet: an approachable set of useful features for people who otherwise would look at a whole other "language" and run away. As for marketing: I'm friends with some of the biggest Minecraft developers in the space; if something's going to be used by new Java developers, it'll be recommended by them. I can even get it packaged into the major modding frameworks for the game if it's intuitive enough, and from there it'll spread by word-of-mouth as long as there's no learning curve at all. It will improve readability, make you have to keep fewer things in your head while writing, and sort through your code easier; there will be no reason *not* to use it, which is exactly what I have in mind. Hell, if the features prove stable enough, we could even pitch them to Oracle for inclusion in the language proper. It'll be a great stress-test for some sorely-needed features in Java. Plus, it'll let me keep track of where my getters and setters are without having to open the Structure tab every five minutes. Win-win. So, have I sold you on it yet? Cheers, Caleb On Mon, Mar 25, 2024 at 11:35 AM OCsite <o...@ocs.cz> wrote: > Caleb, > > On 24. 3. 2024, at 16:57, Caleb Brandt <calebbrand...@gmail.com> wrote: > >> I know you made Groovy, but if you're anything like me, you *love* Java. >> > > just for one, although I haven't co-operated on the Groovy creation (am > just a very satisfied user), I *hate* Java very bitterly. > > The language design is simply *terrible*, all the worse since the people > who made that abomination, i.e., Sun, knew Objective C well (they used to > cooperate with NeXT on OpenStep) and thus *knew* how to do an > object-oriented language right. > > Instead they botched it *terribly*. No real polymorphism. Very limited > encapsulation. Type-system which effectively prevents (or at the very least > makes highly complicated and expensive) all the best and most important > object-oriented patterns like e.g., proxying and message forwarding. > Classes are not objects and their „methods“ do not support inheritance > properly. It is quite normal to access instance variables directly, instead > of consistent usage of accessors. *Heaps and heaps* of boilerplate. > Often, the darned thing limitations just force the IDEs to generate code — > compare e.g., WOLips. Could rant on for months like this :( > > Whilst languages like e.g., Kotlin or Scala fix some of the problems all > right, they, alas, do not allow to switch a big project from the Java > disaster without re-writing it at once and completely, which is a big > show-stopper. > > The vast advantage of Groovy is that you can take a big project, just > rename all *.java to *.groovy, and it will essentially work (well, as > someone already wrote, 99 % — my experience is rather 99.99 %, but indeed > there are things which need fixing and there are a couple of gotchas, but > there's really a very very small number of them). Then you can work on with > the project and gradually change the stupid Java patterns to the pretty > decent Groovy ones, part by part, method by method and if need be, > practically line by line, without losing any functionality during the > process. No other language I know of allows anything like this. > > All the best, > OC > >