Hacker News new | past | comments | ask | show | jobs | submit login

"Dynamic types are, at their core, there to remove the incredible tedium of things like generics or templated types."



I've never felt like templated types or generics are tedious.


Considering the time when it was written, it could mean for example Java's ridiculously long generic declarations which couldn't be inferred or aliased.

Things are much better and more ergonomic these days.

Specific example - some languages will allow you to do:

    fun f(x: int):   // return type inferred
      var foo = something(x)
      return foo
While others need (including type erasure getting in the way):

    Complete<Version<Of<Generic, Foo>>>> f(int x) {
        Complete<Version<Of<Generic, Foo>>>> foo = (Complete<Version<Of<Generic, Foo>>>>) something(x);
        return foo;
    }


I agree, I quite enjoy them in TypeScript where I rely heavily on inference.

I suppose it helps that the types aren't strictly required too, so you can side-step them if necessary.


Type erasure was one of the worst decisions in Java, yeah. Generics and working with types in general is great in C#.


Disagree. Type erasure is actually one of th best possible decisions made by the java designers. Languages that have higher kinded types (Haskell, Scala)are virtually impossible to implement without type erasure. This is why the .net runtime doesn’t have languages with HKT


I don't see how the absence of type erasure could possibly be a restriction. Cast everything to object if you must.

I've literally never run into a situation where I wished type erasure was there but didn't have it, but I've ran into situations where type erasure caused problems in Java and where the absence of type erasure let me do things the way I wanted in C#. typeof(T), new T[], new T(), default(T), etc.


> I don't see how the absence of type erasure could possibly be a restriction. Cast everything to object if you must.

Erasure can be nicer than casting to object everywhere, especially when dealing with interfaces. It means you don't have to define separate interfaces for the erased and specialized cases.

e.g. in Java, implementing List<T> means you also implement List. Meanwhile, in C#, you have to implement both IList and IList<T> if you want to be able to use a collection in an erased context (and even then, the interfaces don't provide exactly the same functionality). Implementing both IList<T> and IList<object> isn't much of an improvement.

> I've literally never run into a situation where I wished type erasure was there but didn't have it, but I've ran into situations where type erasure caused problems in Java and where the absence of type erasure let me do things the way I wanted in C#. typeof(T), new T[], new T(), default(T), etc.

IMO most of these aren't too bad to work around. Although, sometimes erasure can cause problems with reflection and you have to use Guava's TypeToken or something similar.

One definite problem with erasure is that it doesn't play nice with unboxed value types.


The codebase I work with has base classes like Thing, then Thing<T> : Thing, with the parts that don't need the T going in Thing.


Sure, good interface design can ease things, but it doesn't really solve the problem I'm talking about.

In Java, List<Foo> and List<Bar> are the same interface. In C#, IList<Foo> and IList<Bar> are different interfaces that just happen to have similar properties/methods.

This means, in Java you can do

  Object obj = ...
  List<?> lst = (List<?>) obj
  Object item = lst.get(3)
Whereas, in C#, to do something similar, you have to dynamically compile at runtime a specialization of a generic delegate.


You can cast to plain IList and it works as expected. You can even use Add on it.

https://dotnetfiddle.net/jcjchk


Right, but again, it means you're implementing two separate interfaces. You can implement IList without implementing IList<T>, and you can implement IList<T> without implementing IList.


Could you elaborate? How does type erasure relate to HKT?


Yup, that doesn't seem to be a real restriction. Here's a comment on a roslyn issue for dotnet: https://github.com/dotnet/roslyn/issues/2212#issuecomment-98...

> Of course it could be implemented type-erased style, but that's an unpleasant can of worms.

> If it were implemented like C++ templates, it would be a source level feature, meaning you can't have higher kinded polymorphic methods in assemblies. I think we can reach consensus that such a feature would only pollute the language.

> If it were implemented like Java generics, it would lead to all sorts of nonsense. For example you couldn't do typeof(M<>) inside the hkpm, since the type has been erased.

And then a complex-but-good implementation idea follows. Type erasure is not necessary in this case.


The complexity is exactly is issue. So while it’s possible to implement on the .net runtime without type erasure, it’s hard.

Plus the only reason type erasure is bad is if you want reflection. Which in FP languages with a solid type system isnt idiomatic and safe anyway. Edit: value types are one other reason for not using erasure but Can be done other ways




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: