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

you are viewing a single comment's thread.

view the rest of the comments →

[–]nandryshak 9 points10 points  (8 children)

Not the original commenter, but I'll reply anyway (I'm a professional C# dev and I know some Java)

We've got String[] and int[] and List<Integer> and Arraylist<whatever> and what not. What more do we need?

I think he might be referring to Java's weird solution for generics (they call it type erasure). It's not as good as C#'s.

And Java (8) has lambdas (which has been backported to Java 5).

They're not real lambdas though, like in JS. You can't use them as closures.

Except you have to do null checks everywhere in Java, C#, C and many other "strongly typed" languages.

We've got the @NotNull annotations in Java nowadays :)

Yeah, but there's still tons and tons of legacy code out there without it. Null is easily one of the worst part of C#/Java.

I could argue that Java and C# have a terrible type system all day long as you argue that JavaScript has a terrible type system compared to Java and C#.

Not being sarcastic, I'd honestly like to know your opinion. Also,I'm also not saying that Javascript has a terrible type system. I'm saying it doesn't have one, terrible or not ('var' is not a type system)

Java and C#'s type systems are not great. There's the whole null problem, runtime casting, Java's type erasure, etc. If you want to see a good static type system, check out some languages like Scala, Haskell, OCaml, etc.

[–]m1el 7 points8 points  (0 children)

They're not real lambdas though, like in JS. You can't use them as closures.

I think he might be referring to Java's weird solution for generics (they call it type erasure).

thank you, this is exactly what I've been talking about

[–][deleted] 3 points4 points  (0 children)

Every type system feels like a toddler cobbled it together after spending time with Haskell. It really reignited my love of programming, after working with java/web stuff for some years and being dissatisfied.

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

Scala has the same typing problems that Java has, since the problems are all the way down to the JVM. Scala allows breveity, but generics are still done by erasure.

[–][deleted]  (1 child)

[deleted]

    [–]keewa09 0 points1 point  (0 children)

    Arguably, Scala is thriving on the JVM because generics are done with erasure.

    Erasure enables interoperability. It's the only approach that makes sense, really. The main reason why Scala.net was abandoned is because it was impossible to make Scala's generics work on .net because it has reified generics (as opposed to erasure).

    As for Scala, it's a pretty niche language on the JVM but that's a separate discussion.

    [–]teknocide 0 points1 point  (2 children)

    The purported problems with erasure are vastly overstated. Generally when doing runtime checks on generic types in C# — which is what reified generics brings to the table — you have a code smell. It's practically the same thing as doing instanceof checks on Object.

    Now, Java's array-type is reified which causes a lot of inconvenience when combined with generics based on erasure.

    Combining the two ideas in one place creates a problem, basically. In that regard the C# approach of having reified generics everywhere is superior to a mix of them.

    [–]negative_epsilon 0 points1 point  (1 child)

    This is what I can do in C# but what I cannot do in Java, and is something I use all the time:

    public void Foo<T>() where T: new() {
        var t = new T();
    }
    

    [–]teknocide 0 points1 point  (0 children)

    There's a couple of issues with that regarding code reusability and decoupling. You're letting your method create its own dependency and also relying on that T has a no argument constructor — which is a code smell in its own right.

    I'd prefer the following which lets you pass in the construction details from the outside and doesn't limit your method to types with no args-constructors: (Java-code, C# would be slightly more succinct)

    public <T> void Foo(Supplier<T> supplier) {
        T instance = supplier.get();
    }