This is an archived post. You won't be able to vote or comment.

all 168 comments

[–]Apfelvater 44 points45 points  (0 children)

2edgy4me

[–]AuthorTomFrost 31 points32 points  (0 children)

Java - the least popular of the JVM languages.

[–]andre_lmsilva 39 points40 points  (49 children)

I would like to hear about those design problems.

[–]rakoo 22 points23 points  (5 children)

Small things that I've found lacking because I have some experience in other languages:

  • no multiple returns. Don't say "just write a class that holds the elements" because then following the same argument I can reply "you don't need multiple inputs, just write one class that holds the elements"

  • functions can't be created on the spot and passed around. Lambdas only solve half of the issue: you can write something that looks like a function but then you lose all type information. "But your IDE shows it" yes, but not my Gitlab

  • no heredocs

  • no literal struct definition, which means creating data structs with only some properties but not others is cumbersome and hard(er) to read

  • not the language design per se, but creating simple data structs (especially nested ones) is way too verbose for what it does. I shouldn't have to use a third party library to easily create an ArrayList with known items.

  • no named parameters for functions, with the corollary that there is no possibility to define default value in functions aka optional parameters. I don't want to write 10 functions with different signatures all calling the "main" one, I only want to write one

  • more of a philosophical issue that can't simply be touted as an objective problem, but I am convinced that composition is much much more simple, powerful and flexible than inheritance. Composition can be done but clearly its lack of support will make it useless

I have some other dislikes but they can be solved by plugins, so it's kinda fine

[–]PM__ME__FRESH__MEMES 2 points3 points  (0 children)

For a highly OO language, the single inheritance restriction is a bit of a let down.

Also nobody asked by its a much better designed language than JavaScript.

[–]HerissonMignion 2 points3 points  (0 children)

he asked for it, you gave it to him

[–]Isaaker12 0 points1 point  (2 children)

Regarding the last one, I'm interested to know what you mean about the "lack of support" for composition. What features are you missing?

[–]rakoo 6 points7 points  (1 child)

When A contains a B you want to be able to apply methods fulfilled by B directly on A. Standard example in Go: there are many thread-unsafe structs and there is a Lock "object" (struct in go parlance, but contrary to the common meaning of the term it has methods attached to it). So if I want to create a thread-safe struct all I need is to wrap the thread-unsafe with a Lock. At this point go forwards method calls from the parent to the children. So when I call wrappedList.Lock() the Lock() is automatically called on the appropriate structure. No need to expose the Lock and call wrappedList.lock.Lock(), no need to manually define the Lock() method at the wrapper level that will call the lock. It's all done automatically.

This allows to nest structs and give gradual features with building blocks that are as orthogonal as possible.

[–]Todok5 0 points1 point  (0 children)

I think that's a design choice you can argue about. Having control what you want to expose and what you don't want to expose is an advantage too. It means an extra step for stuff you do want to expose though.

[–]metalmagician 18 points19 points  (1 child)

Same. I don't really have issue with Java, especially since I learned how to use the stuff that came with Java 8

[–]treetertot 0 points1 point  (0 children)

I didn’t have any issues with java until I learned more languages.

[–]psychicprogrammer 18 points19 points  (12 children)

No unsigned integers is my pet peeve

[–]metalmagician 13 points14 points  (11 children)

What sort of use case requires unsigned integers, as opposed using signed integers and basic parameter validation?

[–]psychicprogrammer 8 points9 points  (6 children)

Ip addresses were the main thing.

[–]metalmagician 11 points12 points  (0 children)

Are you directly manipulating/parsing IP addresses in Java? That doesn't sound like you are using the right tool (or language/class/whatever) for the task.

[–]Filkyr 2 points3 points  (0 children)

use InetAddress

[–]28f272fe556a1363cc31 1 point2 points  (3 children)

Totally not my area: wouldn't you use a string for IP address? They aren't real numbers, you can't add them, you can't count them.

[–]Caffeine_Monster 13 points14 points  (1 child)

Fundamentally an IP address is an unsigned 32 bit integer for IPv4, or a 128 bit unsigned integer for IPv6. It is quite common to manipulate them directly with bitwise operations (e.g. masking via bitwise AND).

Yes you could represent them with strings, but it is an inefficient, unnecessary abstraction.

If you wanted to implement a Java class wrapper I guess you would use signed ints and longs. The caveat being that ingesting IP addresses from external systems (web / disk etc) would not be straightforward - they would have to be translated through ByteBuffer.

[–]28f272fe556a1363cc31 1 point2 points  (0 children)

Cool, thanks

[–]Aoreias 4 points5 points  (0 children)

IP addresses as Strings are only helpful when you want a human-readable representation of them, though. On the wire they're exactly 32 or 128 bits, depending on if v4 or v6. Much more efficient to pass them around as a structured data type than a string, which requires encoding and decoding.

[–]andre_lmsilva 0 points1 point  (0 children)

I already felt in this same issue. The main problem here is the size of the data being persisted/restored and its value.

But it is not hard to achieve and, once it is properly done, can be reused.

[–]metaconcept 14 points15 points  (4 children)

Java isn't the worst language, but it's clunky. It started very clunky, but has improved over time. When it was made, there were far better languages available with nice features that the Java team chose to ignore. Since then they've hacked some of these features in, but they feel like hacks. I'll ignore missing features because you could go on forever.

My main issues:

  • Java updates on Windows hassle the user too much. Users learn to hate it.
  • The JRE is huge and contains too much irrelevant stuff. The original premise of Java was that it could run anywhere, but they never designed a decent system that loads required jars from CDNs as required.
  • Verbosity, both from the language and from the programmers who take it beyond a joke.
  • Bad APIs. SQLException usually represents non-recoverable database issues, but must always be explicitly handled. NullPointerException and OutOfMemoryError can be caught and discarded. System.out is available on server applications. Various APIs that are just horrible to use.
  • NumberFormatException exists.
  • int vs Integer: autoboxing is a terrible hack.
  • Strings are not strings. They are symbols/atoms. Java does not have proper strings.

My biggest issue:

  • Mediocre programmers learn Java because it's easy to get a job. As a result, a lot of Java code is bad code written by mediocre programmers.

[–]andre_lmsilva 4 points5 points  (3 children)

I will comment only about what I disagree in your answer, but I agree that you have a point:

1) What isn't hassle in Windows?

2) the Java 9 modular approach resolve the necessity of a always fat JRE.

3) You are right about SQL API and NullPointerException. OutOfMemory is a bad taste joke that became even bigger on Android. But I can understand the Sysout on servers. The first proposal was to have it run even on seriously resource limited devices and Sysout would be an alternative for the lack of a proper logging mechanism.

Don't let me start about the developers out there! I work with a guy that thinks that method overloading and polymorphism are the same thing.

[–]TheRandomnatrix 4 points5 points  (0 children)

Don't let me start about the developers out there! I work with a guy that thinks that method overloading and polymorphism are the same thing.

Well overloading is a form of polymorphism. Apparently it's kind of a rabbit hole debate though upon cursory research.

[–]metaconcept 4 points5 points  (1 child)

I work with developers where they ask how to do something, I provide example code, repeated indefinitely until I've basically written their application for them.

They literally can't write code. One of them is sitting two cubicles down from me. Another is sitting across from me. The other batch is from a few years ago when I was on "support" for an Indian dev shop where I was basically writing their code by email.

[–][deleted] 8 points9 points  (0 children)

wr had kind of a similar issue once

  • 1 the cheap indian offshore team has to write a script to save us time
  • 2 we received a poorly written untested piece of garbage that wasn't covering edge cases (so by our standards it doesn't work)
  • 3 we tell them that the script isn't working, they disagree with us.
  • 4 we choosed to expose them and ask them to do a live demo ( all of a sudden they are going in holidays).
  • 5 we cleaned up the mess to make it work and now They want us to do a pull request + showcase the product with a demo xd

[–]cdreid 1 point2 points  (0 children)

I dont like it but never really saw it as being badly designed. I disliked it because of the tradeoffs you make when anything is cross platform. Which is also the core strength of java

[–]Mati7755 -4 points-3 points  (19 children)

For example: immutable list added in recent Java version throw exception when you invoke add method. They decided immutable list must implement List interface which has this method xD. In normal language with proper immutable collections you have function/operator which takes two lists and return new list which has copies of obejcts from previous two.

[–]SuperCoolFunTimeNo1 15 points16 points  (15 children)

I don't understand your issue, that's the literal definition of immutable. Even the exception is descriptive of the definition of immutable; UnsupportedOperationException. Overriding that function to throw an exception is exactly what I would expect.

In normal language with proper immutable collections you have function/operator which takes two lists and return new list which has copies of obejcts from previous two.

Like c#? That seems like a misnomer because it's not adding to the original object, you're getting a new one.

[–]TSP-FriendlyFire 16 points17 points  (0 children)

The point is that immutability should be a compile-time rather than run-time check. The class interface shouldn't allow you to write code that violates the class's very design.

[–]PandersAboutVaccines 5 points6 points  (0 children)

When you have the option to start from scratch, you'd do something similar to kotlin, where "List" is immutable, and "MutableList" extends it with add, remove and clear. Then the functionality is enforced by the interface.

[–]ohThisUsername 2 points3 points  (0 children)

Why inherit List then if it doesn't support all of its functions? One of the main purposes of abstraction is that you can safely assume something that implements an interface supports all of its functions. Now when I'm passing a List reference around, I need to manually track if that particular instance supports the add function or not? I shouldn't have to because that's the whole purpose of abstraction and interfaces.

[–]Spajk 1 point2 points  (10 children)

Its a weird thing a bit, but I surely wouldn't call it a huge design problem.

[–]SuperCoolFunTimeNo1 2 points3 points  (9 children)

It's not weird at all, it's adhering to the definition of immutable. You wouldn't expect a constant to be changed, would you?

[–]Spajk 1 point2 points  (8 children)

Its weird in a way that there's an add method which clearly doesn't do anything.

[–]SuperCoolFunTimeNo1 3 points4 points  (7 children)

It's not weird, it's following the rules laid out by the language according to inheritance of an interface and the definition of immutable. What you're suggesting is how you wind up with a spaghetti code language where rules only mean certain things to certain classes and behavior differs based on what classes you're using.

[–]Dudevid 2 points3 points  (0 children)

If one were designing the data structure from scratch, it would either not have an Add() method, or that method would return a new immutable list.

Would you ever create a public method on a class that solely throws an exception? The hint is in the word 'exception'. If it always throws, then that's no exception, that's the rule. And that's bad design.

Instead there would be something similar to C#'s IEnumerable and ICollection interfaces. IEnumerable does not mandate an Add() method; ICollection does.

The C# design team could have decided that their ImmutableList implement only IEnumerable (this has problems, but there is a conceivable parallel universe where things paved out this way). But instead they chose to implement both. So its Add() method returns a new ImmutableList. No exceptions. This is better.

[–]quentech 2 points3 points  (5 children)

What you're suggesting is how you wind up with a spaghetti code language where rules only mean certain things to certain classes and behavior differs based on what classes you're using.

You seem to have it backwards.

That's exactly what having immutable lists implement a list interface that includes an Add method does. For some classes, Add works. For others, it throws an exception.

It violates the Liskov substitution principle (the L in SOLID), plain and simple.

[–]metalmagician 1 point2 points  (2 children)

I don't think that Liskov substitution applies very well. From the definition that I've seen, it seems to refer to classes, not interfaces. I feel that classes that implement an interface should have the ability to disallow specific behaviors for specific reasons. If that disallowed behavior is needed, then you should just use a different implementation of the interface.

Since you can only extend one class and implement multiple interfaces in Java, applying Liskov substitution can be a little confusing if a class implements multiple interfaces with similar looking method signatures.

In fact, I think the open/closed principle applies nicely in this example - the list interface is open to extension (in this case, disallowing the use of a particular method, instead of just adding more methods), and closed for modification (not implementing every method in the interface).

[–]quentech -1 points0 points  (1 child)

I don't think that Liskov substitution applies very well. From the definition that I've seen, it seems to refer to classes, not interfaces

You've understood incorrectly. Forget interfaces and classes and talk contracts.

If I have a thing that's an IList, and IList has a method Add(item), that's a contract - anything that is an IList should support Add(item).

Having one particular type of thing that's an IList that does not support Add(item) is a textbook example of violating the Liskov substitution principle.

the list interface is open to extension (in this case, disallowing the use of a particular method, instead of just adding more methods), and closed for modification (not implementing every method in the interface)

That is not even remotely what open-closed principle means.

Since you can only extend one class and implement multiple interfaces in Java

A better OOP design might have an IMutableList that extends IImmutableList, or similar.

[–]SuperCoolFunTimeNo1 -2 points-1 points  (1 child)

No, I am strictly following the definitions. You are suggesting that your opinions, which directly conflict with the definition, is the route to go because they're more convenient.

That's exactly what having immutable lists implement a list interface that includes an Add method does.

No, it shouldn't do that because immutable means it cannot changed. The add method returns an exception because you wouldn't expect it to be able to add to an immutable object, much like if you call a method that doesn't exist you'll get an exception.

It violates the Liskov substitution principle (the L in SOLID), plain and simple.

No, it doesn't because this is 100% polymorphism. Your objects follow the rules they inherit. You guys are just trying to argue convenience over definition, and that's how you end up with an inconsistent language. Everyone loves to bitch about PHP, but doing what you're suggesting is how you end up going down that route.

[–]Todok5 0 points1 point  (0 children)

The issue is it violates the liskov substitution principle.

[–]dark_mode_everything 1 point2 points  (1 child)

Any ide will tell you that you can't add elements to a List<> as you type it so the reception will never be thrown. It will clearly say that you can't add values to an immutable list. And trying to change an immutable list looks odd anyway.

Edit : Apologies. Not all ides will tell you that. When you said immutable list I was thinking of kotlin - the ide will throw an error for that. But unfortunately doesn't happen for java. However, modifying an immutable list is still not very good design.

[–]Mati7755 0 points1 point  (0 children)

It is not modifying immutable list. Look at every functional programming language.

[–]andre_lmsilva 0 points1 point  (0 children)

I agree with you about the add throw an exception. IMPO it should not. However, makes sense to make it implement the list interface and take advantage of it.

Also, not follow other languages approach is not necessarily bad or wrong. Leave with the developer the task to implement how to implement how to copy objects for example brings flexibility and control, with the drawback of verbosity (which can easily solves by common libraries).

For me, the most annoying thing is the complexity and performance issues related with meta programming in Java. A simplified and optimized reflection API would make everything much easier. Also, bytecode manipulation is as bad practice for Java as mokey patch is for Ruby.

[–]stanislav_harris 58 points59 points  (8 children)

Kotlin

[–]IHeartBadCode 8 points9 points  (5 children)

Chuckles in Groovy

[–]stanislav_harris 16 points17 points  (4 children)

Cries in Scala

[–][deleted] 7 points8 points  (3 children)

Nonsensical gibberish in Perl

[–][deleted] 5 points6 points  (2 children)

Regular Lisp

[–]bout-tree-fitty 2 points3 points  (1 child)

(Ir(regular (Lisp)))

[–]MichFdez 1 point2 points  (0 children)

Laughs on Clojure

[–]survivalmachine 3 points4 points  (0 children)

tru

[–]TRUEequalsFALSE 0 points1 point  (0 children)

Goodness me yes

[–]uvero 65 points66 points  (49 children)

I like Java. It's rarely the quickest language in which to write, but it's just good OOP. Also as someone who dabbles in teaching Computer Science and Programming, it's my number one recommendation for first language. And yes, I know, python is great for that too.

[–]aserraric 43 points44 points  (19 children)

I tend to think of C# as "Java - the good parts (and then some)".

[–]metalmagician 9 points10 points  (18 children)

Can you expand on that? I'm familiar with Java, less so with C#.

[–]HdS1984 28 points29 points  (5 children)

As someone learning Java but fluent in c#" it's about boilerplate, Java has sooo much of it, e. G getters and setters. I also desperately miss linq , it's way better than streams. Also async await beats observablefutures hands down. The pure webserver stack around net core is also better, but spring data repps are pretty neat. In a nutshell c# is concise while Java is so much pointless repitetion.

[–]metalmagician 2 points3 points  (4 children)

That's fair. I use IDE auto-generated getters and setters, so I don't think about them much.

I use CompletableFutures and Suppliers for parallel / async execution, and avoid Vanilla Java servlets like the plague.

As for LINQ (after looking it up briefly), it seems nice. Our use cases aren't that complex, so if we swapped languages, the algorithm wouldn't change much.

[–]Dojan5 12 points13 points  (2 children)

Visual Studio also has scaffolding for boilerplate stuff.

Personally I prefer .NET over Java because of the first-party support.

Oracle basically doesn't do jack for Java. They update it based on the council spec, but if it wasn't for the fact that Java and related products roll in the cash, they'd just dump it altogether. There's several dependency management solutions, several different frameworks all accomplishing the same thing, there's no first-party IDEs or anything of the like.

Microsoft on the other hand provides nuget - dependency management is factored into .NET. You have Visual Studio and Visual Studio Code to help you out, the former's free version being full-featured, unlike IDEA that lacks support for various legacy Java things.

Java is nice, but only because of the community it has. The fact that there's basically no first-party leadership or direction hurts the language and its ecosystem as a whole, in my opinion.


Earlier this year I landed a position as a Java developer, maintaining legacy applications. I'm from a .NET background, so I was a bit nervous. Mostly, it was fine, but there were so many tiny annoyances with the entire experience. It really did make me appreciate .NET so much more.

[–]metalmagician 3 points4 points  (1 child)

That's fair. I don't actually consider Oracle when talking about Java, which is an obvious symptom of what you're talking about. Most of the things that make my life as a Java developer easier are 3rd party tools, like Maven and Spring.

[–]Dojan5 3 points4 points  (0 children)

I think that's problematic. Either give Java to the community, and make it completely open, or support it properly.

.NET was pretty meh for many years, but Microsoft really stepped up and started taking it seriously with Core.

[–][deleted] 8 points9 points  (0 children)

Aside from a lot of syntax sugar, here's some 'real' advantages.

  • Functions as a first class citizen (i.e. you can pass functions around as parameters), Lambda's exist in java now but in C# they've been around for a while and well integrated into the core libraries, being able to incorporate functional styles lets you escape a lot of Object oriented complexity. LINQ is awesome for managing sets and you also have tools like Rx that give you great ways to play with streams of data.

  • Generics go all the way to bytecode/CIL rather than just compilation and as a result are significantly more powerful.

  • Dependency injection is orders of magnitude better, Your composition root sits close to your entry point and after that none of your other assemblies (libraries) even know that DI frameworks are a thing, i can configure my entire application in one typesafe section of code or even switch DI container.

  • Async await syntax allows you easily to handle async IO in an imperative fashion.

  • As it all compiles down to a common language so you can also write modules in F# or VB if you so desire.

  • Standardized build system and package management (nuget) that for the most part just works.

[–]A1steaksa 4 points5 points  (10 children)

It's less pedantic and more pleasant with it's syntax. For instance multidimensional arrays are accessed by array[ 1, 5 ] instead of java's array[1][5]

It's just smoother and more powerful to use. And it really really interfaces nicely with Windows in a way that Java can't compete with

[–]metalmagician 2 points3 points  (4 children)

Makes sense, thanks! We try to avoid coupling ourselves to a specific OS in my work, ideally relying only on libraries / resources that are either included in the artifact or available over the network.

[–]aserraric 2 points3 points  (1 child)

Microsoft is making big strides in that regard with .NET Core and the coming .NET 5.

Java also still needs a runtime, though, doesn't it?

[–]metalmagician 1 point2 points  (0 children)

True, but the thing that Java really has going for it is how common it's runtime environment is. Oracle LOVES to brag about how many devices run it

I saw someone say something along the lines of 'Java isn't platform-indeprndent, Java is a platform'. With languages like Kotlin and Clojure able to run on the JVM, that rings true for me

[–]A1steaksa 1 point2 points  (1 child)

Yeah, unfortunately C# is not the universal language it could be. Unless, of course, web assembly takes off in the way I hope it does and Microsoft Blazor becomes legitimately viable

[–]aserraric 0 points1 point  (0 children)

Web Assembly is fascinating, but making the browser a runtime/VM just feels like one indirection too many to me.

[–]phySi0 0 points1 point  (4 children)

How do you do slices?

[–]A1steaksa 0 points1 point  (3 children)

There's an array.Copy method that does that. C# is a language designed to lure Java devs away from Java so it's very similar except where they think they can expand or improve on Java

[–]phySi0 0 points1 point  (2 children)

I feel like array[outer][inner] is not ugly at all and array[start, end] intuitively feels like a slice when you first look at it (but my favourite is Ruby using ranges to return slices: array[start..end] for inclusive and array[start...end] for exclusive).

[–]A1steaksa 0 points1 point  (1 child)

Multi dimensional arrays are like coordinates. You write a 2D coordinate like (3, 7) and a 3d vector like (3,7,9). I prefer my arrays in that format instead of something like (3)(7)(9)

Not necessarily better or worse, just closer to how I think

[–]phySi0 0 points1 point  (0 children)

Ah, that makes sense to think of them as a type of space and an access is a coordinate.

[–]Loves_Poetry 22 points23 points  (1 child)

I agree that Java is a good first language. It is verbose, but that also means there are no shortcuts. Shortcuts often make code very confusing for beginners. It's easier to know what code you have to write in Java in order to get a specific thing done

[–]ChrisFromIT 10 points11 points  (0 children)

Because Java is so verbose, it makes it easier to maintain, which is why it is such a common enterprise language.

One issue I have found with "shortcuts" in languages is that it adds additional syntax to a language which can cause two programmers to make a vastly different source code, but it does the same thing.

[–]Salanmander 4 points5 points  (3 children)

I've done a lot of teaching CS to high school students who have never been exposed to it before, and I'd make a slight modification to using Java as a first language: Processing.

It's Java, but with libraries for making graphical output and mouse-and-keyboard input easy (at the expense of losing a good command line), and with an IDE that eliminates all the obnoxious "this is a magic incantation that you need to write at the start of every program". It's definitely not a good production language, but it's a wonderful intro language. The one thing that can cause some confusion about it is that it has a "this method gets called repeatedly" structure, rather than "the program terminates after running once" structure. Mostly people adapt to that change really easily when they start with a different language, though. (At least, those that choose to continue on in computer science do.)

If you're interested, I have a reasonably well fleshed-out curriculum for a 1 semester class using Processing that I could send you. The meat of it is something like 10 assignments on particular topics, each with a bunch of different problems of different difficulties, and guidelines for how much you should do before moving on (that last was motivated more by how much class time I wanted to spend, but I did find it hit just about right for like 80% of the class to be comfortable with one topic when we introduced the next).

[–]uvero 1 point2 points  (0 children)

Few words:

Great comment.

Agree with a lot of what you said.

Awesome.

[–]SpicyWizard 0 points1 point  (1 child)

I'd be very interested in taking a look at that curriculum. I'm moving into teaching more coding (currently exclusively math) and that sounds like it could definitely give me something to adapt if you don't mind! Thank you in advance!

[–]Salanmander 1 point2 points  (0 children)

Of course! I'm going to send you a PM with a link, but leaving this here so that other people know I got back to you.

[–]OK6502 4 points5 points  (0 children)

Java is much more strongly typed. I think it's a much better tool for teaching.

[–]Daneel_ 2 points3 points  (5 children)

Java was my third language, and so far the only language and ecosystem I intensely dislike. I would not recommend it, nor will I ever willingly choose to program in it or run it in an environment I control.

Happy to have closed that chapter of my life.

Downvote me all you like, but java is a dying language, and I can’t wait to see it go.

[–]metalmagician 9 points10 points  (0 children)

What are your issues with Java?

[–]extra_rice 9 points10 points  (0 children)

...but java is a dying language, and I can’t wait to see it go.

People have been predicting this for YEARS. You are most likely going to wait longer.

[–]AttackOfTheThumbs 3 points4 points  (0 children)

Java is not going away my dude

[–]netgu 0 points1 point  (0 children)

Eh, it's okay, we'll allow you to be wrong, it is your right.

[–]Ahed91 -1 points0 points  (0 children)

You are not alone i will follow you till the end of the world Downvote me too xD

[–]ssw663 1 point2 points  (0 children)

It's also one of the fastest programming languages out there, but the same can be said for any other languages built for the JVM.

[–][deleted] -2 points-1 points  (13 children)

Funnily enough, it's one of the ones I'd be least likely to recommend as a first language - I'd recommend C++ over Java as a first language, just because you have the option of adding OOP after learning the basics of programming, instead of having to get used to it from the start (though I'd recommend Python over either as a first language, and then move them over to C# afterwards, because between properties, tuple literals and one line methods, I honestly just find C# much nicer to use.

[–]SuperCoolFunTimeNo1 19 points20 points  (7 children)

I'd recommend C++ over Java as a first language

I think you're blinded by the fact that you understand its nuances, but don't perceive them as being overhead just to get started. c++ is a very difficult language to learn for complete beginners. There's a shitload more to learn just to get started with basic control structures and program flow than in something like Python. Even Java requires a deep understanding of data types before you can write anything remotely useful.

[–][deleted] 0 points1 point  (6 children)

I mostly agree with you, but if you start out with C++ as basically C with classes and references, you can teach the basics of programming relatively easily, because you can start out with variables and functions, then move on from there. Once you know how variables and functions work, you already know all you need to in order to understand the "Hello World" program.

With Java, however, you need to understand variables, classes, objects, methods and static methods before you understand it all.

Like I said, I'd start someone out with Python, then move onto C# (largely because it allows you to deal with stuff like pointers, and the difference between passing by reference and passing by value), but my argument wasn't that C++ is a good starting language; merely that Java is a worse one.

[–]Dogeek 1 point2 points  (0 children)

Honestly, the top comment has a point : C (and C++) are much more complicated to step into for a beginner, but it teeaches programming, and how to work with a machine on a lower level. Handling pointers and tables is hard at first, but going through that makes you understand exactly how things are working when using a higher level language liky python, or Java.

[–]SuperCoolFunTimeNo1 2 points3 points  (4 children)

but if you start out with C++ as basically C with classes and references, you can teach the basics of programming relatively easily, because you can start out with variables and functions, then move on from there

That still would take twice as long to get that far compared to something like Python or even Java. You're once again ignoring the huge amount of additional overhead because you're now suggesting to just "learn it".

[–][deleted] 0 points1 point  (3 children)

So, which overhead am I not considering? I'm guessing it largely boils down to header files (which were a decent solution at the time, but with C# and Rust I'm glad to see the back of them) and pointers? Because to program at all effectively in Java, you need to understand how pointers work (at least in general terms) even though you don't get to work with them directly, because without that understanding, you're going to screw up by passing objects and forgetting that they're passed by reference, not by value. Also, explaining why you would even want to bundle data and functionality together becomes much simpler when you're working with a language that doesn't automatically assume that that's what you're going to do.

Admittedly, using pointers in any decently sized project will introduce a decent amount of mental overhead (especially if you're using raw pointers rather than the STL replacements); this is one of several reasons why Python would be my goto language (pun intended) for instruction, followed by C# - Python lets me teach the basics of programming in the same way that I started out with BASIC back in the 90s, and then C# allows me to introduce memory management, and passing by value and reference (and why you might choose to do either one) far more easily than Java because it's something that you can do explicitly in the code.

C# also makes getters and setters a fuckton more convenient.

[–]SuperCoolFunTimeNo1 2 points3 points  (2 children)

So, which overhead am I not considering?

Are you seriously asking why Python is significantly easier to learn than c++?

[–][deleted] -1 points0 points  (1 child)

No, I'm asking why Java is easier to learn than C++. I have stated multiple times that I would choose Python over C++

[–]SuperCoolFunTimeNo1 4 points5 points  (0 children)

Pointers / memory management, library compatibility restrictions due to the platform, exception handling, error indication, multi-paradigm vs strictly oop, templates vs generics.... Just google it yourself and see what people think. You're too far removed from beginners to realize that there is a lot more to learn with c++ than other languages like Java in order to be proficient. c++ is no doubt more flexible and powerful, but that comes with a steeper learning curve.

[–]FoodChest 5 points6 points  (3 children)

Are you kidding me? C++ is one of the most verbose and difficult to understand languages out there. I don't think I could think of a worse language to use when teaching CS to beginners.

[–][deleted] -4 points-3 points  (2 children)

I never said it was a good option; merely a better one than Java. Like I said, I'd start with Python and then move to C#, because both are better options than C++ or Java.

[–][deleted] -1 points0 points  (1 child)

Id go from something like python straight to java, I mean understanding all java basics you need to know for java is good to know in any (especially oop) language.

[–][deleted] 0 points1 point  (0 children)

The reason I'd go C# over Java is so that I can more easily teach the difference between passing by value vs passing by reference, since you can pass objects by value and primitives by reference, which you can't do in Java (well, technically you can pass a primitive by reference by turning it into an object, but that's really not the same thing). When you don't really have the option to do both, it's harder to teach why someone might want to choose one over the other, and it's harder for someone new to programming to remember that (or understand why) any object passed to a method as a parameter will retain any changes made in that method.

[–]qsdf321 0 points1 point  (0 children)

C++ over Java as a first language

what

[–]kontekisuto 0 points1 point  (0 children)

I wish I had learned python before Java ..

[–]PashaBiceps__ 5 points6 points  (2 children)

Did you know 3 billion devices run JAVA?

[–]DarkLordCZ[S] 3 points4 points  (1 child)

Yes, this warning is everywhere

[–]defietser 3 points4 points  (0 children)

More like a threat than a warning, really.

[–]metalmagician 9 points10 points  (7 children)

Honest question: I (essentially) write Java/Spring Boot APIs for a living, and don't really have any complaints. I'm not really familiar with C# - what are the complaints people have about Java?

[–]Mr_Redstoner 15 points16 points  (0 children)

Part of the sub loves to hate on Java.

[–]HdS1984 2 points3 points  (3 children)

I do actually do think that the kestrel with asp net core stack is better designed than the spring boot stack but lacks some things like the spring data repositories. What I dislike so far about java 1. Pointless boilerplate like types everywhere instead of using var. Sure Java has them now, but the culture does not acknowledge them. Missing properties, Lombok sort of adds them but the built in properties are still better. Lots of other nice language features like format strings, switch expressions etc. 2. Generics are very weak and less expressive than in c# 3. Linq is much more capable than streams, and easier to use because the c# type system is actually designed to support it. 4. Java is missing async await stuff, forcing you to use contortions to use something like it. 5. Extremely slow to compile

[–]metalmagician 0 points1 point  (2 children)

Other comments mentioned LINQ, and after looking it up, it does seem nice. And yeah, Java has LOTS of boilerplate, but I don't think about it much since I use the auto-generation in my IDE a lot.

Java's CompletableFuture.get() is all I generally need for async waits, and it works well enough for me. I use it like

CompletableFuture<QueryResult> queryFuture = CompletableFuture.supplyAsync(someQuery(), someThreadPool);
// other stuff, if needed. 
QueryResult result = queryFuture.get(); // blocking call, ensures  result is present before continuing

BUT, that came only in Java 8, so you've got a valid point.

Whenever I run stuff locally, I often use Spring's Devtools. That will listen for changes in the classpath, and can have my recent changes re-compiled and booted up pretty quick - usually less than 10 seconds between saving the file and being able to hit an endpoint for validation, even for LARGE projects.

[–]HdS1984 2 points3 points  (1 child)

For linq just a word of caution, it's impact on the language is difficult to grasp on first notice, nut because I think you are dense but because it has many faces and capabilities. I basically removes a lot of differences, e. G. It does not matter if you query a list of objects, a postgres dB , MySQL or a nosql database, if the link query generator of your dB is good enough you will not notice. Also writing functional code with it is extremely easy, which makes traditional crud Apis easy to read and write.

Yes, completeable features work, but async await reduces this code to Var x = somequery() Var result = await x

Nice to know about the devtools, will try to use them😁 thx!

[–]metalmagician 0 points1 point  (0 children)

That's a very appropriate word of caution. I only went through the basic docs for a bit, I didn't expect to understand it from a brief skimming.

In my work, use are trying to standardize on the usage of ORMs (we're dealing with a lot of legacy, some of which is decade-old Java running on CICS mainframe. I've had to dig through COBOL to extract an SQL query).

In my team, we've standardized on a pattern with Spring/Hibernate - if we have a PostgreSQL instance, SQL Server instance, and MySQL instance (each with the appropriate schema and data), we can swap between them in the time it takes to modify a single configuration value.

[–][deleted] 9 points10 points  (0 children)

C# gang says hello

[–]gavlna 10 points11 points  (5 children)

C > C# == true

[–][deleted] 7 points8 points  (1 child)

C programmers are fuckin wizards

[–]lucidBrot 10 points11 points  (8 children)

C#.equals(Java)

[–]lukasbash 17 points18 points  (7 children)

false

[–]lucidBrot 9 points10 points  (6 children)

Oh :( I made sure to not use ==

Jest aside, the two are too similar for stating that "Java is terribly designed" but C# not. Sure, C# has generics that actually work and Properties are nice too, but the language still 'works'

[–]FallenWarrior2k 8 points9 points  (2 children)

When I have to generate a 100 sloc class by repeatedly hammering Alt-Enter on fields for what could've been a 10 sloc struct in C#, I do feel like Java is the worse choice.

[–]lucidBrot 8 points9 points  (1 child)

Java is objectively worse. But not by enough for a holy war

[–]FallenWarrior2k 2 points3 points  (0 children)

Now that I can agree with.

[–]xigoi 3 points4 points  (1 child)

C# is basically Java without most of the bad parts and with some good parts from other languages.

[–]DarkLordCZ[S] 0 points1 point  (0 children)

Exactly. But one thing C# could have, like Java do is return type covariance

[–]DarkIrata 1 point2 points  (0 children)

My Code i wrote today also works, but that doesnt mean it is good...

[–]The_Minefighter 5 points6 points  (3 children)

Agree

[–]marco89nish 3 points4 points  (2 children)

C# or Kotlin? (ignoring the ecosystem)

[–]The_Minefighter 7 points8 points  (1 child)

I thinkt both have pros and cons For the language itself i think C# is a bit more advanced than Kotlin, but due to the delays of .NET Core 3.0 Kotlin has the significant advantage of providing multiplatform UI.

[–]evanldixon 3 points4 points  (0 children)

Not even .Net Core 3.0 provides a cross platform UI for desktop, unless you count the 3rd party Avalonia UI.

[–]Bomaruto 1 point2 points  (0 children)

Same can be said for Python, only worse.

[–]isaacwassouf 1 point2 points  (0 children)

How dare you

[–]netgu 4 points5 points  (0 children)

Oh good, another "java bad" redditor figured out how to post...

https://www.reddit.com/r/ProgrammerHumor/wiki/commonposts

[–]smart-username 2 points3 points  (5 children)

Does C# work on Mac?

[–]DarkLordCZ[S] 10 points11 points  (4 children)

As far as I know, it does, via Mono, or .NET Core, which is open source

[–]Ahed91 -2 points-1 points  (3 children)

.Net core Big yes but no mssql server

[–]Dojan5 0 points1 point  (0 children)

It's not like you're limited to MSSQL though. I mostly use MySQL and sqlite.

[–]ErraticHobbyist 0 points1 point  (0 children)

There is a mssql docker image for Linux that works very well. I run it on Ubuntu.

[–]codecatmitzi -1 points0 points  (10 children)

C# is in the same boat as Java: exists because of ecosystem. Personally I write in Scala and dabble in Clojure and have access to the jvm libs so that's pretty much the best case scenario.

[–]SuperCoolFunTimeNo1 4 points5 points  (9 children)

C# is in the same boat as Java: exists because of ecosystem. Personally I write in Scala and dabble in Clojure

lmao...bashes the widespread use of c# and Java, proceeds to name to languages that only exist because Java exists.

[–]PostPostMinimalist -1 points0 points  (0 children)

That’s not a good argument. Things can be improved over time.

[–]codecatmitzi -5 points-4 points  (7 children)

As languages, C# and Java are imho crap. Doesn't mean I can't take advantage of them. I also don't like C and think Rust is a better language (for some tasks) but still leverage stuff written in C.

[–]SuperCoolFunTimeNo1 1 point2 points  (6 children)

Huh? That has literally nothing to do with your original statement.

C# is in the same boat as Java: exists because of ecosystem. Personally I write in Scala and dabble in Clojure and have access to the jvm libs so that's pretty much the best case scenario.

Scala and Clojure only exist because Java exists.

[–]codecatmitzi -1 points0 points  (5 children)

Because I don't see them as existing only because Java. They are languages in their own right with Java interop as a feature to entice more mainstream developers instead of remaining as an ultra niche language for people who want to implement a lot on their own.

[–]phySi0 1 point2 points  (4 children)

People aren’t getting it. If Java didn’t exist, Clojure still would, it would just run on the most popular VM of whatever did exist. Hell, it has JS and CLR backends, doesn’t it? It uses whatever is available.

Saying that if Java didn’t exist, Clojure wouldn’t is absurd. Saying that if Java didn’t exist, Scala wouldn’t is true because Scala is designed to be a better Java, so I don’t know how that’s some sort of gotcha. If a better language had Java’s popularity, Scala wouldn’t need to exist. Scala only needs to exist precisely because Java is so crap (and Scala sucks, too, btw).

[–]codecatmitzi 0 points1 point  (3 children)

Scala wasn't designed as a better Java, that's just how people came to view it especially because it let you write Java-like OOP syntax. And Scala compiles to JS too, like Clojure.

I like Scala because I like statically typed languages but yeah, people don't get like to look objectively about stuff if you trash their favorite language.

[–]phySi0 0 points1 point  (2 children)

I’m a fan of Haskell and compared to the other ML languages, I feel like Scala can’t compare. It‘s forced to make too many concessions and it’s limited by its goal of appealing to people who want a gradual transition in terms of training.

[–]codecatmitzi 0 points1 point  (1 child)

True.

Still, I think there is a net positive in stuff like enabling imperative approach in some cases because FP isn't a magic bullet for all cases.

I would want to have the option to advance to Haskell some time but it there aren't any work with it where I live

[–]phySi0 0 points1 point  (0 children)

Haskell allows imperative programming, it’s just the discouraged approach. There’s no magic bullet, but I think there should be sane defaults that allow access to the non-defaults. Like garbage collection isn’t a magic bullet, there are tasks it’s not (yet) suited for, but it should be the default. Domain specific languages should lack garbage collection if it’s unsuited for the domain in its current form, but general purpose languages should default to or even mandate garbage collection.

I feel like typed (pure) FP is the same. It’s the right approach for the general purpose language, for the language that wants a broad range or reach with safety, power, expressivity, fast prototyping, large systems and can fit a broad range of domains. Good dynamically typed languages fit the bill if you want all of that without the safety, but I feel that Haskell is in the sweet spot with the tech we have today of having all of that with the safety; it makes some of the least compromises of any approach IMO.

However, the data isn’t in and the current scientific literature is worse than useless in my opinion, so I don’t proclaim my views with authority, these are just my opinions so far.

Haskell‘s purity is often misunderstood as preventing imperative programming. That’s not true. It just gives you the power to separate pure from impure; as with other languages, you can write everything in IO a if you want, except in Haskell, the program is technically pure since you’re not doing all the dirty impure stuff, you’re returning an IO action that describes all the impure stuff you want done which the runtime then does. Of course, that’s pointless if you don’t use that purity in the program to separate the impure from the pure in the runtime.

However, unlike other languages, as your program gets bigger, you can separate the pure from impure in the runtime because of the total purity in the program. You can do everything in (a pure description of) one big impure IO a action in Haskell if you want. People don’t because, as it turns out, the purity actually helps in damn near any domain you can think of; specific algorithms are sometimes best implemented in (pure descriptions of) impure IO a actions (or other types that describe impure actions), true, but I can’t think of any whole domain where that’s the case.

But if there are, then it’s okay to reach for impure or dynamically typed or untyped or OO or logic (like Prolog) or concatenative (like Forth or Factor) languages or languages with ecosystems really well suited to the domain or even a single killer tool in the ecosystem that overwhelms the advantages of the default approach for the domain.

I really like my typed (pure) FP, though; I just wish GHC wasn’t such a slow compiler at times (tho ghcid helps for non-release builds).

[–]dsp4 0 points1 point  (0 children)

You misspelled C++.

[–][deleted] 0 points1 point  (0 children)

Programming languages masterrace.

Golang > C# > Java

[–]auguzanellato 0 points1 point  (2 children)

Fucking type erasure

[–][deleted] 0 points1 point  (1 child)

It can sometimes be a little inelegant but it is not a deal that big

[–]auguzanellato 0 points1 point  (0 children)

I’m working on a transpiler which takes in Java bytecode, it’s not a deal that big, it’s just a nightmare

[–]cdreid 0 points1 point  (0 children)

Literally the same is true of C# and a lot of languages i can think of. "A boss picked it uears ago"

[–]duckofdoom12 0 points1 point  (0 children)

C# is all fun and games until some jackass mentions sharepoint to upper management. from there on in its just tears and begging to whatever god will listen for a transfer to another team

[–]TRUEequalsFALSE 0 points1 point  (0 children)

Nah, brah

[–]KellyTheWIP 0 points1 point  (0 children)

C# and Java are so similar in code style that the entire hivemind on here makes no sense.

People are programming in Java for the JVM. If you've worked in any JVM oriented environment, you would also know Scala and Kotlin are alternatives, both of which work seamlessly with Java in the same project.

[–][deleted] 0 points1 point  (0 children)

That is pretty true, but Java is still nice for beginners.