Live data from Hacker News

Jodd – The Unbearable Lightness of Java

jodd.org

231–239 of 239 posts

Re: Jodd – The Unbearable Lightness of Java

#231
post #226

Earlier quoted context omitted.

The go version looks perfectly fine to me (saying this as someone who uses clojure every day) ;) Something else to consider is performance, in most implementations the for loop is going to be more efficient.

That's exactly my complaint- most languages have eager, mutable, non-persistent, collections because they were not designed with functional programming in mind. Then FP became the hot new shit, so they all added some of the lowest hanging fruit so that people can say absolutely weird things like "I do FP in C#". The problem is that the majority of these implementations just eagerly iterate the collection and make ful…

If you really want to go wild, take a look at https://www.vavr.io/ (formerly jslang). You can make programming in Java as functional as you want.

Re: Jodd – The Unbearable Lightness of Java

#232

Earlier quoted context omitted.

Here's a Java example that sums the populations of a list of Countries: int population = countries.stream().mapToInt(Country::getPopulation).sum(); The Go implementation: var population = 0 for _, country := range countries { population += country.Population } It gets more perverse if you need to flatMap, or transmute components of map types, etc. If you want even more power, take a look at https://github.com/amaembo…

Ah. You know what? I forgot that the Java implementation of these concepts isn't stupid like it is in some other languages (except what the heck is mapToInt? Some optimized version that makes a primitive array, I guess? Yucky- I wish the compiler could just figure that out). So, I concede that Java's addition of the stream API is a legitimately good example of adding an aspect of functional programming to an otherwis…

Yeah, mapToInt is annoying because the primitive/object dichotomy in Java is annoying. No question about it, it's a wart on the language. Though it does offer some optimization abilities, so the dichotomy is not completely meritless - it's easy to understand why the language designers did it this way. Maybe project valhalla will fix this someday, I don't know. In the mean time, it's not a fatal flaw.

Re: Jodd – The Unbearable Lightness of Java

#233

Earlier quoted context omitted.

That's exactly my complaint- most languages have eager, mutable, non-persistent, collections because they were not designed with functional programming in mind. Then FP became the hot new shit, so they all added some of the lowest hanging fruit so that people can say absolutely weird things like "I do FP in C#". The problem is that the majority of these implementations just eagerly iterate the collection and make ful…

If you really want to go wild, take a look at https://www.vavr.io/ (formerly jslang). You can make programming in Java as functional as you want.

I have to admit, that looks pretty slick.

Have you used it? I'd be curious to hear how well it works in practice.

It seems like the only "big" things Scala has over this is its implicits (which so many people hate, but have been really improved in version 3) and its for-comprehension syntax.

It's so interesting to see a bunch of projects converge on really similar things. You look at Scala, at this Vavr stuff, and at Kotlin + Arrow.kt, and they're implementing all of the same stuff over Java.

Re: Jodd – The Unbearable Lightness of Java

#234
post #227

Earlier quoted context omitted.

So, I don't agree with your assessment at all. Writing a large enterprisey business app in Rust will likely run faster, have fewer bugs, use less memory, and even scale out better. That's true but which is more flexible for the "ever changing living business app domain" the GP is alluding to? You seem to keep ignoring this part, flexibility matters. In rust is easy to code yourself into a corner and spent lots of tim…

Fair. You're right that I didn't address that concern. I guess the problem is that I don't know what we mean by "flexible". The GP did mention lifetimes around the same part of their comment, so I assume that there's some concern about business requirements changing in some way, and that Rust's lifetimes would get in the way of adapting to code to meet the new requirement. Is this also what you mean by "code yourself…

If you have two interfaces, Foo and Bar, in Java, and you want to write some code that does something special for a type that is both Foo and Bar, what do you do? It's been a while, but if I remember correctly, you have to define a new interface called FooBar that extends Foo and Bar and you have to go find every class that implements both Foo and Bar, and change them to implement FooBar, instead. In Rust, I can just write a function: `fn do_stuff(o: T)`. Done. Didn't have to define a new type, didn't have to touch old stable code, etc.

Since Java 8 there is static and default methods in interfaces.

Curious, what rust sql query builder are you refer to?

Re: Jodd – The Unbearable Lightness of Java

#235
post #227

Earlier quoted context omitted.

So, I don't agree with your assessment at all. Writing a large enterprisey business app in Rust will likely run faster, have fewer bugs, use less memory, and even scale out better. That's true but which is more flexible for the "ever changing living business app domain" the GP is alluding to? You seem to keep ignoring this part, flexibility matters. In rust is easy to code yourself into a corner and spent lots of tim…

Fair. You're right that I didn't address that concern. I guess the problem is that I don't know what we mean by "flexible". The GP did mention lifetimes around the same part of their comment, so I assume that there's some concern about business requirements changing in some way, and that Rust's lifetimes would get in the way of adapting to code to meet the new requirement. Is this also what you mean by "code yourself…

Rust is great for reliable production systems, for sure, but for 'let's quickly prototype this new feature', it’s too strict. Imagine figuring out a perfect algorithm and spending a few hours implementing it just to be told by the borrow checker it won’t let it pass.

When this new features start to queue up I’m happy to have leaks as long as I get to try out ideas quickly (later you hardened them). And it’s hard to convince Rust to let it go.

Maybe it's my inexperience with Rust, definitely need to give it a second try for more than three weeks but haven't had a good reason to do so.

I don't like Java at all and prefer Clojure when on the JVM, but as you said, the Java ecosystem(libraries get the job done) and the GC are definitely good reasons to pick it up for a webapps.

Re: Jodd – The Unbearable Lightness of Java

#236

Earlier quoted context omitted.

Fair. You're right that I didn't address that concern. I guess the problem is that I don't know what we mean by "flexible". The GP did mention lifetimes around the same part of their comment, so I assume that there's some concern about business requirements changing in some way, and that Rust's lifetimes would get in the way of adapting to code to meet the new requirement. Is this also what you mean by "code yourself…

If you have two interfaces, Foo and Bar, in Java, and you want to write some code that does something special for a type that is both Foo and Bar, what do you do? It's been a while, but if I remember correctly, you have to define a new interface called FooBar that extends Foo and Bar and you have to go find every class that implements both Foo and Bar, and change them to implement FooBar, instead. In Rust, I can just…

> Since Java 8 there is static and default methods in interfaces.

That's not relevant to the part of my post that you quoted...

I was describing a hypothetical situation where you already have two interfaces, but would like to have functionality that only makes sense for an object that implements BOTH of those interfaces. The only way to do that in Java is to write a THIRD interface that combines the two and then go through and change your implementations to implement that new interface instead of the two separate ones.

However, in the bullet point above, I mentioned static methods on traits in Rust, which is different than what static methods on interface in Java are. In Java, a static method on an interface is just a function on the interface, itself. In Rust a trait can declare that an implementing type must have a static method matching the signature. This is because Rust traits are type classes, while Java interfaces are just object interfaces and cannot constrain the implementing type, itself.

> Curious, what rust sql query builder are you refer to?

I have been mostly using mysql_async (https://docs.rs/mysql_async/latest/mysql_async/), but recently started playing with sqlx (https://github.com/launchbadge/sqlx). I guess "query builder" isn't the right way to describe them, but I'm not sure what else to call them...

Re: Jodd – The Unbearable Lightness of Java

#237
post #235

Earlier quoted context omitted.

Fair. You're right that I didn't address that concern. I guess the problem is that I don't know what we mean by "flexible". The GP did mention lifetimes around the same part of their comment, so I assume that there's some concern about business requirements changing in some way, and that Rust's lifetimes would get in the way of adapting to code to meet the new requirement. Is this also what you mean by "code yourself…

Rust is great for reliable production systems, for sure, but for 'let's quickly prototype this new feature', it’s too strict. Imagine figuring out a perfect algorithm and spending a few hours implementing it just to be told by the borrow checker it won’t let it pass. When this new features start to queue up I’m happy to have leaks as long as I get to try out ideas quickly (later you hardened them). And it’s hard to c…

> Rust is great for reliable production systems, for sure, but for 'let's quickly prototype this new feature', it’s too strict. Imagine figuring out a perfect algorithm and spending a few hours implementing it just to be told by the borrow checker it won’t let it pass. > When this new features start to queue up I’m happy to have leaks as long as I get to try out ideas quickly (later you hardened them). And it’s hard to convince Rust to let it go.

I don't know. This is starting to feel like moving the goalposts.

The first person I replied to claimed that Java's ecosystem is high quality and that serialization and data-mapping is not only good in Java, but that it's not better in any other language.

I showed that both of those claims are false.

Then they claimed that Rust, being a systems language, was not suited for enterprise apps with evolving requirements. And you kept me honest about addressing the evolving requirements part.

I explained how Rust apps will run better, scale better, be more robust and bug-free, AND allow us to better adapt to changing requirements than Java.

And now, of course, it's some other reason that Rust can never work.

I'm sorry for the snark, but it always seems to be the EXACT same common talking points over and over again when it comes to Rust nay-saying, and after having worked with Rust on-and-off over the last 4-5 years it just gets exhausting hearing about all of these hypothetical things that don't happen in real life, from people who haven't actually used Rust in a real project, but somehow seem to know what it's good and bad at (and what a coincidence! It's bad at the exact thing they're working on, and the language they chose for the task was definitely the best choice! I'm happy for them, but it's discouraging to know that I'm the only person who ever makes the wrong choice sometimes.).

I mean, it's literally always even the same words. It's always "prototype" and "quick and dirty" and "that darn borrow checker!". You'd think that everyone on HN and Reddit were Thomas Edison with all of the "prototypes" they're writing.

I mean, what exactly do you think is going to happen in your quick prototype Rust code? A reference to a piece of data is going to come out of nowhere and sink your experiment? Hell no. At worst, you're going to type `.clone()` and `.unwrap()` a bunch of times to take copies instead of references and crash on any errors, and call it a day. If this is experimental-prototype-whatever, then what the heck do you think you're doing writing a bunch of fancy lifetimes and cross-thread mutable data sharing?

This shit doesn't happen.

You know what does happen when I try to "prototype" in a "good" prototyping language like Python or JavaScript? I spend a bunch of time re-running the same code over and over and over until I stop forgetting or misspelling what keys are on the dictionary I passed to the function, or accidentally passing arguments in the wrong order.

When I "prototype" in Java, I can't figure out if my algorithm sucks or not because I accidentally wrote `o1 == o2` instead of `o1.equals(o2)` or I forgot that getting a `null` from a Map could mean that the key has no entry in the Map *or* that an actual `null` value was inserted into the map for that key. Or, I get an NPE because I accidentally mixed up `int` and `Integer` somewhere.

I've already spent too much time on this. If you decide to give Rust another shot some day, that's great. If not, that's fine, too. There are probably other languages that will give better bang for your buck, too, like OCaml or Scala (3). I like Clojure as well, even though I prefer my static types. Clojure is at least a well-designed and consistent language. Java is a hot-mess.

EDIT: Also, if the borrow checker won't let your algorithm pass, it almost definitely means your algorithm has a race condition that you might not have realized. "You're welcome for not letting that crap eventually end up in prod" - Borrow Checker

Re: Jodd – The Unbearable Lightness of Java

#238
post #235

Earlier quoted context omitted.

Rust is great for reliable production systems, for sure, but for 'let's quickly prototype this new feature', it’s too strict. Imagine figuring out a perfect algorithm and spending a few hours implementing it just to be told by the borrow checker it won’t let it pass. When this new features start to queue up I’m happy to have leaks as long as I get to try out ideas quickly (later you hardened them). And it’s hard to c…

> Rust is great for reliable production systems, for sure, but for 'let's quickly prototype this new feature', it’s too strict. Imagine figuring out a perfect algorithm and spending a few hours implementing it just to be told by the borrow checker it won’t let it pass. > When this new features start to queue up I’m happy to have leaks as long as I get to try out ideas quickly (later you hardened them). And it’s hard…

Fair, I'll shut up until I have more real world experience with Rust. One thing that I remember well that really annoy me were the extremely slow compile times (these was two years ago, maybe it's much better now) since I value fast feedback. I understand for some that compile time cost is worth it and doesn't bother them.
Post reply on HN