Ask HN: Any alternative to Java (OOP) which has the same ecosystem?

17 points by SpacePortKnight ↗ HN
I've professionally programmed in Java, Python, Haskell and JavaScript.

Of these, I've found Java to be easiest when dealing with large code bases ( > 100,000 LOC ). It is complied, has a strong type system, very good standard library, good & mature build systems, and excellent tooling with IDEs like IntelliJ.

However, I am not a fan to object oriented programming. I suppose I am looking for a C / Python / Haskell like language with the same ecosystem / popularity as Java.

I tried Go, but it looks like Go is built to programmed on internet connected devices only. With Java, dependencies can even be downloaded and put as Jars.

42 comments

[ 3.0 ms ] story [ 102 ms ] thread
What is your beef with OO?
- High memory usage

- Several patterns introduces a lot of boiler code.

- It's harder to visualize a OO codebase than a pure FP codebase like Haskell.

- Frameworks like Spring / Jakarta are overly complex.

But I don't mind OO, it's just that after using Haskell and Python, it just feels a little messy.

What kind of stuff have you built in Haskell?
> - High memory usage

There is nothing about OO does enforce higher memory usage compared to other patterns. In fact it might be better than functional programming, which relies on a lot of closures (which all need heap allocations). The fact that Java does not support value types will require more memory for a certain set of applications than e.g. Go or C# - but that is barely related to OO.

> - It's harder to visualize a OO codebase than a pure FP codebase like Haskell.

This will be rather subjective. Be sure to have a common understanding with your team about it if you are not the only contributor to a codebase.

> There is nothing about OO does enforce higher memory usage compared to other patterns.

Many OO languages offer dynamic/virtual dispatch of methods as a primary (and sometimes only) way to do polymorphism. This comes at a non-zero memory cost, because each object needs some additional runtime type information.

> In fact it might be better than functional programming, which relies on a lot of closures (which all need heap allocations)

Closures do not need heap allocations. Rust has closures and allocates them on the stack (unless you deliberately box them). I don't know Haskell, but I believe it could do the same.

Sounds like the exact use case for Kotlin.
You might find you like C# better than Java then.

C# has objects, structs, primitives. Sugar to get rid of boiler plate. And increasingly a lot of functional features.

You can vendor your go dependencies the same way as you can java. Go is perfectly happy developing on non internet capable devices. In fact after vendoring the go tool will happily serve all of your documentation via command line or localhost web server so you don't have to go searching the web. It may deserve a closer look from you.
You have tried Scala or Clojure?
I used to hate the JVM, Clojure changed my mind so much. I am glad I found it.
F#? Since it’s still in the .NET ecosystem which is huge, plus it’s functional.
I have zero knowledge in this.

What is the experience of developing on .NET on Linux or Mac?

Does it even work?

Yes.

For IDE use Rider or VSCode

Thanks, what about using them on Linux desktop?
Yeah no problems at all. As the other user mentioned, I’d highly recommend using Rider as your IDE since you won’t be able to use proper visual studio (imo Rider is better than VS anyway).
Thanks.

I have heard about Rider, but in the context of APL, and not F#.

Can you tell me if I can develop for .NET on Linux and then deploy the app on the web or on Linux desktop?

Yes, it will run on Linux. Most people creating new .NET applications are running them in Linux containers in prod.
Kotlin does both functional and object-oriented programming very well. It also has near-perfect interoperability with Java, so you can reuse your existing libraries without any hassle. And it works well with standard build tools like Gradle.
Don't extend classes in Java, only implement interfaces.

You can go so far as to prohibited extending classes using static analysis tooling.

You can make them final. This is especially useful when writing libraries.
Even better.

Or sealed if the usecase applies.

Newbie OO q: What’s the benefit/use case of sealing or making an object final? My experience is in javascript so I wonder why I’d ever need something like Object.seal or Object.freeze. Is it really that difficult to maintain object instances that do not change after some point?
It's just a tool to enforce the hierarchy in code. Once the codebase gets big it's hard to remember all the details about your API.
Go can be deployed as link-able shared binary if you want.
Give Scala a try. It has Java interop and your programs get packaged into jars (by default). I had experience with the same set of languages as you (including Haskell!) when I discovered Scala and it's my favorite language these days. As a bonus, you get to use (if you want) functional effect systems like Cats Effect and ZIO.
I second Scala. And the learning curve can be as gentle as you like, especially given you can leverage all the libs you've been using in Java land, too.
Few mentions here of Clojure. It's well worth exploring; a strong ecosystem behind it.
Scala? With some help from additional libs such as Zio (https://zio.dev/) it allows you to write production quality programs like you would in Haskell on top of the JVM quite quickly...
I second this one.

Scala borrows a lot from Haskell and Python too. Definitely a JVM and integrates with Java well.

I coded in Java since 2002, now in Scala since 2013, and I am learning Haskell as well.

> I tried Go, but it looks like Go is built to programmed on internet connected devices only. With Java, dependencies can even be downloaded and put as Jars.

What's wrong with "go mod vendor" ?

From golangbyexample.com:

"It will create a vendor directory inside your project directory. The vendor directory will have all the direct and indirect dependencies downloaded. You can also check in the vendor directory to your VCS (Version Control System). This becomes useful in the sense that none of the dependency needs to be downloaded at run time as it is already present in the vendor folder checked into VCS."

Kotlin. Its compatibility story with Java is great (although you obviously will lose some benefits such as guaranteed null-safety when interfacing with Java code). It's multi-paradigm and supports FP well, as well as DSLs. You probably can't (or shouldn't) go as crazy with your types as in Haskell or Scala, but you do get more or less concise sum (sealed classes) and product (data classes) types, as well as generics. Plus, if you use IntelliJ, the tooling is great.
If you're placing a strong importance on ecosystem, and after something that can be used in a less-OOP / more functional style, it's hard to go past TypeScript (whatever distaste you may have for the dark corners of JavaScript).

A less vibrant ecosystem, but far stronger on the functional and string typing, take a look at OCaml (others have suggested good alternatives like F# or Scala if you want to leverage the existing VM-based ecosystems).

Python is great because you can make it as OOP as you want, or avoid objects all together.

You can make it strongly typed with type hints and MyPy type checking, or you can avoid it all together.

You can do imperative programming, or functional.

And best part, you can do all of that in one code base depending on what the use case is. And the debugger is great.

And just want to point out since it's not explicitly stated-- you can run Python on the JVM with the Jython project (although only Python2 compatible)
Just curious because I don't understand exactly what you mean, could you go in more details about why you don't like go?
The great thing about the JVM is a lot of languages run on it and you get access to the same ecosystem from any of them. If you like Python, I had a great experience with Jython. It was really easy to interoperate back and forth between Jython and Java. The only major downside is it implements Python2 and is not expected to move forward to Python3.

It's a good choice if you don't expect to pull in modern Python libraries, just do basic scripting and pull in JARs when needed instead.

Thank you for the recommendations. I will be sure to check out Scala and go through your suggestions.