News for hackers. Stuff that matters.
Re:What to Know Before Debating Type Systems (2008) by weinzierl on Friday May 03, 2019 @03:58PM (#19821727)
Chris Smith - who wrote the original piece years ago - added a current prologue to the text. I think part of it is an excellent summary so I quote this part here:

> If pressed for an answer, though, yes I still do believe in the central conclusions of the article. Namely:

> That “static typing” and “dynamic typing” are two concepts that are fundamentally unrelated to each other, and just happen to share a word.

> That “static types” are, at their core a tool for writing and maintaining computer-checked proofs about code

> That “dynamic types” are, at their core, there to make unit testing less tedious, and are a tool for finding bugs.

> That the two are related in the way I outline: that one establishes lower bounds on correctness of code, while the other establishes upper bounds, and that questions about their real world use should come down to the possibility and effectiveness of addressing certain kinds of bugs by either computer-checked proof, or testing.

EDIT: When I wrote this comment the post linked to Steve Klabnik's 'reprint' of the temporary lost original article. Currently it links to the original. The 'reprint' missed the prologue.

Re:What to Know Before Debating Type Systems (2008) by StefanKarpinski on Friday May 03, 2019 @07:38PM (#19823218)
Doesn’t hold water, imo. If dynamic and static typing were really independent concepts, then why are languages only one or the other, never both? I explained my take on dynamic versus static typing here:

https://stackoverflow.com/a/28096079

> The primary difference between static and dynamic languages, in my view, is this: in static languages, expressions have types; in dynamic languages, values have types.

Read the rest of the answer for more details in the context of Julia, which, as a dynamic language with a sophisticated type system, really crystallizes the distinction.

Re:What to Know Before Debating Type Systems (2008) by ken on Saturday May 04, 2019 @12:45AM (#19824511)
As explained in the article:

> "The dichotomy between static and dynamic types is somewhat misleading. Most languages, even when they claim to be dynamically typed, have some static typing features. As far as I’m aware, all languages have some dynamic typing features. However, most languages can be characterized as choosing one or the other. Why? Because of the first of the four facts listed above: many of the problems solved by these features overlap, so building in strong versions of both provides little benefit, and significant cost."

It's a bit like asking: If electric and gasoline motors are independent concepts, then why are cars only one or the other, not both? Well, some are, to varying degrees. Most aren't, because it adds a lot of complexity. I don't see any inherent contradiction here, nor do I even find the relative unpopularity of hybrid systems terribly surprising.

Re:What to Know Before Debating Type Systems (2008) by andrewflnr on Friday May 03, 2019 @09:10PM (#19823620)
> in static languages, expressions have types; in dynamic languages, values have types

This kind of agrees with OP in practical terms, despite using opposite terminology. A type applied to an expression (syntax) is expressed as a proof about that syntax, and a type of a value at runtime is expressed in code that can safely crash in the face of an ill-typed operation. They both constrain program behavior, but do it with such radically different mechanisms that it's easy to argue they're fundamentally different. It depends on whether "fundamental" should be about mechanism or purpose. Let us know when you've solved that problem. :)

Julia's type inference can be seen as finding proofs of the properties of certain expressions and, if it finds them, using them to optimize the dynamic typing code, basically eliminating dead branches for type checks that can't fail. I'm tempted to think of languages with nominal subtyping as being hybrids as well: the base class is the static type, and the runtime class is the dynamic type.

Re:What to Know Before Debating Type Systems (2008) by sgeisenh on Friday May 03, 2019 @10:06PM (#19823855)
Who said languages were only ever or the other?

All languages have some notion of static types and dynamic types. They're most easily bucketed by whether they consider more than one type.

C is statically multityped but dynamically unityped. Python is statically unityped but dynamically multityped. Haskell, since it uses lazy evaluation, is statically multityped and dynamically multityped.

The main issue with static unityping is that insufficient testing can easily lead to type errors in production (or worse). And static multitypes help static analysis tools reason about code more easily.

Introducing a new type that is intended for use in a specific context that can easily be tracked is tremendously useful when programming at scale.

Re:What to Know Before Debating Type Systems (2008) by Tomte on Saturday May 04, 2019 @01:13AM (#19824598)
But C++ has static and dynamic types, and a C++ programmer needs to understand both.

For example, in inherited methods the selection of the method implementation is based on the dynamic type of the (pointer) value, but the selection of the default arguments is based on the static type of the value.

Re:What to Know Before Debating Type Systems (2008) by thesz on Sunday May 05, 2019 @05:15AM (#19831893)
Given algebraic type (as in Haskell - data List a = Nil | Cons a (List a)), you can have static type verification (map :: (a -> b) -> List a -> List b) and dynamic dispatching for situation in concrete part of a program:

  pairwiseReduce :: (a -> a -> a) -> List a -> List a
  pairwiseReduce f (Cons a1 (Const a2 as)) = Cons (f a1 a2) (pairwiseReduce f as)
  pairwiseReduce f as = as
We fix the type, but concrete instantiation of a type may vary in run-time, so we pattern-match: the list can have at least two elements (first case) and we reduce them and the rest of the list or it has less than two elements and we leave it as it is.

I took my time and read about Julia's type system. It is really the worst from both worlds: it does not allow for tagged unions (like List I declared above), it does not allow for adhoc polymorphism (1+2 gives error for floating type and evaluates for integers), there are no type classes (that adhoc polymorphism thing) and, thus, no good guarantees for whatever substitution for GADTs Julia has. And it also has inheritance which makes type inference exponentially harder in simple cases.

So I urge you to take your time and read about Haskell's type system. It really allows you to have static and dynamic types and vary their presence and utility as you see fit.

Re:What to Know Before Debating Type Systems (2008) by KenoFischer on Sunday May 05, 2019 @07:35AM (#19832295)
ML Style constructors are not particularly idiomatic, but you can write basically the same thing in Julia:

    struct Cons{T, S}; head::T; tail::S end
    pairwiseReduction(f, a::Cons{T, Cons{S, Tail}}) where {T,S,Tail} = Cons(f(a.head, a.tail.head), a.tail.tail)
    pairwiseReduction(f, a) = a
(https://github.com/thautwarm/MLStyle.jl if you want the syntax) but that's somewhat beside the point.

I think the primary problem here is one of terminology. Take Stefan's quote from the post you're responding to:

> The primary difference between static and dynamic languages, in my view, is this: in static languages, expressions have types; in dynamic languages, values have types.

There is a clash in terminology here. People coming from a static languages background would use the term "tag" for what dynamic languages people call a type. There isn't really a super good word in the dynamic languages world for what static languages people call a type, and the word type is generally re-used, since the distinction isn't as important (generally there is an embedding of the tags into the type system, so using "type" for both can be sensible). I'm gonna adopt (my best interpretation of) the static languages terminology here for this comment.

Some languages have both types and tags. The biggest difference then between static and dynamic languages are which of the two is primarily dispositive (in the sense of determining the semantics of the language). In dynamic languages, the tags are, in static languages the types are. This choice has deep seated implication for the kind of programs that can be written and the behavior of the program.

In fact, you sometimes end up in situations where static languages have multiple tag systems (but generally only one type system) and dynamic languages have multiple type systems (but generally only one tag system). In julia, the tag system is primary, but we have a very rich type system that is embedded in the tag system by parametricity and is used for dispatch. This type system is constructed in such a way that the subtyping relationship is induced by tag system (for types T, S, (T <: S iff for all values v s.t. tagof(v) <: T, tagof(v) <: S)) [1]. You basically want to choose a decidable type system that satisfies this constraint, but is at the same time sufficiently expressive to be useful for what people want to do.

We also have another, larger type system that is used for inference judgements, but that is generally transparent to the user. It is in principle possible to type check over any of these type static system, but type checking is not part of the semantics of the language.

The problem with statements like "Julia's type system does not allow for X", is that it presumes that the type system having some feature is a pre-requisite for having the corresponding functionality. So while Julia's type system does happen have support for unions (and universally qualified unions), the significance of that is for dispatch, not for whether the language can have expressions that can take on values of different tags.

In any case, I can assure you that many people working on Julia are well familiar with Haskell's type system. Hopefully I was able to convince you that there is at least something interesting about the way Julia's type system works.

[1] I should credit the Northeastern PL group for the term "tag-based semantic subtyping" here to describe this notion (https://github.com/julbinb/ftfjp-2019/blob/master/paper/mini...).

Re:What to Know Before Debating Type Systems (2008) by jcelerier on Saturday May 04, 2019 @03:29AM (#19825002)
> then why are languages only one or the other, never both?

what do you mean by that ? multiple statically-typed languages have "var" or "any" types which can be used to go from the static to the dynamic typing world.

Re:What to Know Before Debating Type Systems (2008) by chongli on Saturday May 04, 2019 @09:39AM (#19826370)
"Any" types do not imply dynamic typing. Languages like Haskell are purely statically typed yet do not require explicit, concrete types for everything. Type inference is the feature which bridges this gap.
Re:What to Know Before Debating Type Systems (2008) by jcelerier on Saturday May 04, 2019 @12:25PM (#19827403)
type inference and "any" types are completely different. e.g. in C++,

    auto var = 123;
is inference, but

    std::any var2 = 123; 
is dynamic typing, because you can do `var2 = "foo bar";` unlike the first case.
Re:What to Know Before Debating Type Systems (2008) by vraid on Saturday May 04, 2019 @07:06AM (#19825725)
Typed racket has both dynamic types and static typechecking.

https://docs.racket-lang.org/ts-guide/

Your objection doesn't really hold water..

Re:What to Know Before Debating Type Systems (2008) by DiseasedBadger on Friday May 03, 2019 @04:59PM (#19822223)
Maybe I agree?

To me, the purpose of those proofs, is to tell the compiler about all the programs I'm not writing. So that it doesn't emit them.

Also: documentation.

Re:What to Know Before Debating Type Systems (2008) by namelosw on Saturday May 04, 2019 @07:57AM (#19825899)
> That “static types” are, at their core a tool for writing and maintaining computer-checked proofs about code

> That “dynamic types” are, at their core, there to make unit testing less tedious, and are a tool for finding bugs.

They are not rival. Imagine a gradual typing design, it has a statically typed system, but it won't stop you from running it. The type errors would only be suggested in IDEs and stop building on CI environment but you can run it anyway. Then you can have both checked proofs and debugging advantages. (Dialyzer for Erlang is an example but there could be more strict typing)

Another similar topic is 'compiled' and 'interpreted', instead of static and dynamic types. 'Compiled' is runtime favored because the code was compiled is ready to be executed a lot of times, while 'interpreted' was executed once on demand because you may change your code at any time, so there's no point compile it for one person. Plus source code is much easier to debug than byte code.

It would be interesting to see languages could have solid static/dynamic/compiled/interpreted at the same time. Elixir/TypeScript/F#, etc. are good examples but this idea can definitely go further.

Re:What to Know Before Debating Type Systems (2008) by msla on Friday May 03, 2019 @04:44PM (#19822098)
>> That “dynamic types” are, at their core, there to make unit testing less tedious, and are a tool for finding bugs.

To the extent this is true, it's true because modern dynamic type systems are fairly strong. They enforce a contract about what operations are valid on a given type, and you can't usually get out of the contract. If you can cast in Python like you can cast in C, I don't know about it.

Part of the problem is that we've lost a whole quadrant of languages in the static-dynamic weak-strong graph: Weak dynamic typing is nonexistent these days.

We used to have it. B and Bliss were both weakly dynamically typed languages. Extremely so, in that they only had one datatype: The machine word. Since literally any operation was valid to perform on a machine word, there was no way for the type system to disallow anything, so it faded into irrelevance. Much like Bliss, in fact.

That's taking it to an extreme, shoving the "weak" part of weakly-typed so far that the language is untyped, like assembly language is usually regarded as being.

Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @05:46PM (#19822582)
> If you can cast in Python like you can cast in C, I don't know about it.

Note that "cast" and "coerce" are different. Python supports coercion but not casting. Casting is an operation done in static type systems where you tell the compiler "I know this has type X, but pretend it has type Y". Coercion is a run-time operation which moves data from a box of one type into a box of a new type (i.e., a new object is allocated).

> Part of the problem is that we've lost a whole quadrant of languages in the static-dynamic weak-strong graph: Weak dynamic typing is nonexistent these days.

I'm not sure what you mean by "the problem" here. Weak dynamic type systems are, in my opinion, the worst of all worlds. They provide neither compile-time checks nor runtime checks that really amount to much. I don't know why you would ever prefer a weak dynamic type system in a language.

JavaScript is essentially weak and dynamically typed. The weak part comes from all the implicit coercions the language inserts to ensure your code nearly always produces some result. This is terrible because it makes identifying errors exceptionally more difficult than in a strong or static type system.

Re:What to Know Before Debating Type Systems (2008) by msla on Friday May 03, 2019 @07:03PM (#19823034)
> Note that "cast" and "coerce" are different. Python supports coercion but not casting. Casting is an operation done in static type systems where you tell the compiler "I know this has type X, but pretend it has type Y". Coercion is a run-time operation which moves data from a box of one type into a box of a new type (i.e., a new object is allocated).

Right. I know this, I just call coercion "autoconversion" because the data is typically given a new form as well as a new box. Having autoconversion without casting is a sign of a strong type system, because you can't turn off the type system, you are only allowed to use it. If there's no way to autoconvert from type A to type B, that's it: You can't turn a value of type A into one of type B by hook or by crook.

> I'm not sure what you mean by "the problem" here.

"Problem" in the sense of our discussion being incomplete, nothing more.

> Weak dynamic type systems are, in my opinion, the worst of all worlds. They provide neither compile-time checks nor runtime checks that really amount to much. I don't know why you would ever prefer a weak dynamic type system in a language.

I agree with all of this.

> JavaScript is essentially weak and dynamically typed.

Wrong, for the reasons I went over in other posts.

Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @07:15PM (#19823098)
Ah I didn't realize I had replied to the same person in different places. Sorry about that haha.

> I know this, I just call coercion "autoconversion" because the data is typically given a new form as well as a new box.

Hmm interesting. I think I dislike this because coercion is not always automatic, so the "auto" part of "autoconversion" is a hang-up for me. For example, doing `int("3")` in Python is an explicit coercion, but I don't think it would qualify as an "autoconversion" (unless I'm not quite understanding your definition of that term). In the interests of clarity until I understand better, I'll continue using "coercion" and I'll specify implicit vs. explicit as needed.

> Having autoconversion without casting is a sign of a strong type system, because you can't turn off the type system, you are only allowed to use it.

I agree for explicit coercion, but not with implicit.

If your coercion is implicit, then the user has no control over what's going on. The type system is essentially transforming values' types behind the curtain in an effort to prevent errors. This means that errors which the user might believe should be raised may not be. The type system is "weak" because it's not holding types rigidly with respect to the user's perspective. The user's perspective is key, because if we look at things from the language's perspective then almost any language could be viewed as strongly typed given the right theoretical framework.

> "Problem" in the sense of our discussion being incomplete, nothing more.

Totally fair!

Re:What to Know Before Debating Type Systems (2008) by saghm on Friday May 03, 2019 @04:57PM (#19822206)
> Weak dynamic typing is nonexistent these days

Is JavaScript not considered to be at least partially on the weak side of the spectrum? Things like using the `+` operator on arrays and objects and getting back numbers and integers seems to be to be weak typing.

Re:What to Know Before Debating Type Systems (2008) by msla on Friday May 03, 2019 @05:24PM (#19822425)
> Is JavaScript not considered to be at least partially on the weak side of the spectrum? Things like using the `+` operator on arrays and objects and getting back numbers and integers seems to be to be weak typing.

I might be in the minority on this, but I draw a distinction between stuff which gives odd results but is defined and controlled, and stuff which is unspecified and only 'defined' to the extent the machine does... something when you do it.

Everything Javascript does is in the first camp. Autoconversion is specified, it's part of the language design, and the implementation handles it. What C does when you use casts to turn a string of chars to a double and add the result to some other value is undefined, and whatever the hardware happens to do is what happens.

So doing a lot of autoconversion to the point you can feed any value to any function and no errors happen greatly reduces the value of dynamic typing in making testing easier. However, the implementation is still keeping track of types, because it's doing the autoconversions for you.

The Javascript equivalent to Bliss is using stringly typing to the extent your only language-level datatype is the string, and every other type only exists in the programmer's head. But that's not a property of the language as much as it's a property of the specific codebase.

Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @05:48PM (#19822597)
> I draw a distinction between stuff which gives odd results but is defined and controlled, and stuff which is unspecified and only 'defined' to the extent the machine does... something when you do it.

Whoa, this is totally orthogonal to the strong/weak typing distinction.

Traditionally, strong/weak typing refers to how easy it is to "trick" the type system into doing something it wouldn't otherwise want to do. C is weakly typed because you can cast things all over the place and do whatever you want with the actual values, regardless of what type they're "supposed" to have. This is completely unrelated to undefined behavior.

Re:What to Know Before Debating Type Systems (2008) by msla on Friday May 03, 2019 @07:00PM (#19823021)
> Traditionally, strong/weak typing refers to how easy it is to "trick" the type system into doing something it wouldn't otherwise want to do.

Right, and autoconversion according to spec is something the type system does want to do. It uses type information to do it, in fact.

Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @07:07PM (#19823057)
I feel like I'm not explaining myself well haha.

The C type system is perfectly happy with casts. The behavior of casting is well specified. And yet the fact that the type system supports casts to the extent that it does means that C's type system is weak.

But this is not the only metric to judge a type system's "strength", and it was poor word choice on my part that I phrased my statement in a way that made it seem so.

JS's type system is weak because of implicit coercion. The fact that values of type X can be coerced into values of type Y at runtime without any notification to the user is indicative of a weak type system, regardless of how well-specified this behavior is. Weak type systems do not lack specification; they lack a feeling of types being "rigid" or "strong". If your values can be converted to different (semantically incompatible) types, then your type system is weak because it isn't telling you anything.

A strong type system is one which stands up to you and says "No, I won't let you do that because I don't think that's what you meant to do." A weak type system is one which does its best to let you do whatever you want. Again, the specification of the behavior of various operations within the type system (such as casting or coercion) is not the determining factor in assessing the "strength" of the type system.

Re:What to Know Before Debating Type Systems (2008) by dllthomas on Friday May 03, 2019 @07:17PM (#19823108)
> A weak type system is one which does its best to let you do whatever you want.

... or plain doesn't care?

Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @07:22PM (#19823136)
Maybe? I think that phrasing is lacking in some clarity. Does Python care? Most people would say "no", but Python is strongly typed because you simply cannot use values with the wrong attributes. (The nominal types don't matter in Python, generally, but the structural types do.)
Re:What to Know Before Debating Type Systems (2008) by dllthomas on Saturday May 04, 2019 @12:19AM (#19824406)
Python says no in a (sufficiently) sensible way at runtime to certain classes of things, and tries to let you do what you want about others. I was referring to things like undefined behavior in C as instances where the language "plain doesn't care" what you want.
Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Saturday May 04, 2019 @01:44AM (#19824697)
I don't think UB has any particular bearing on a conversation about the "strength" of a type system, actually. There are plenty of non-type-related UBs, and those UBs that are related to types do not necessarily make the type system weaker. C's type system is weak due to things like explicit casting that can circumvent any type safety, for example.

Python does no runtime checks of types. The type system employed by Python is effectively a structural (not nominal) system. So long as you provide things with the right structure (i.e., your objects provide the correct fields/methods), everything will work. But many people would like say that Python just "doesn't care" what you want because of the lack of any nominal type checking at any point.

Re:What to Know Before Debating Type Systems (2008) by dllthomas on Saturday May 04, 2019 @12:07PM (#19827301)
Any UB is type-related, in that "anything can happen" destroys type safety regardless of what definition of type safety we're using.
Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Saturday May 04, 2019 @01:33PM (#19827890)
UB does not mean "anything can happen".

UB just means that the language specification makes no assertion about how to handle a given case — the behavior is literally just not defined. Any implementation of the language could choose to raise an error for such cases and that would conform correctly to the standard.

Re:What to Know Before Debating Type Systems (2008) by dllthomas on Sunday May 05, 2019 @02:14PM (#19834103)
Note that I specifically said "undefined behavior in C", where it pretty much means exactly that. It is not the same as "implementation defined". It's true that an implementation could in theory respect types even in the case of undefined behavior, but it is not promised by the language spec.
Re:What to Know Before Debating Type Systems (2008) by michaelsbradley on Friday May 03, 2019 @05:19PM (#19822385)
JS facilities such as `typeof`, `instanceof`, `Array.isArray`, and built-in support for protocol checking (e.g. `Symbol.iterator`), and many related runtime facilities — despite their warts and limitations — place the language's dynamic typing in the strong camp.
Re:What to Know Before Debating Type Systems (2008) by DonaldPShimoda on Friday May 03, 2019 @09:53PM (#19823791)
I don't think the presence of these facilities grants a type system a "strong" classification. None of them actually enforce anything on their own — they're just functions and expressions that are provided to the programmer to implement their own dynamic type-checking via introspection/reflection. They do not, on their own, constitute a strong type system.

Python is strongly typed because you cannot use a value of type X in a position where a value of type Y is expected. But Python doesn't check in advance — it just tries to go and do the thing. The trick to this is that Python's type system is actually structural instead of nominal; it doesn't care what the name of anything is, so long as it's got the right fields. (This is where we get "duck typing" from.) But you can't, for example, have Python do `"3" + 2`. A runtime error will result, because the language does not perform any implicit coercions.

JS is different. There are some native implicit coercions from certain types to other types. The presence of these makes JS's type system weaker than Python's, so in general I see it grouped as "weakly typed".

Re:What to Know Before Debating Type Systems (2008) by michaelsbradley on Sunday May 05, 2019 @01:01PM (#19833706)
You can try the following in a browser's JS console or in a NodeJS REPL:

   > for (const x of [1,2,3]) { console.log(x); }
   1
   2
   3
   undefined
   
   > for (const x of {a:1,b:2,c:3}) { console.log(x); }
   TypeError: {(intermediate value)(intermediate value (intermediate value)} is not iterable

So, sometimes JS automatically performs type conversions. But it also has the same kind of type-related runtime errors as Python. It just depends what you're doing.
Re:What to Know Before Debating Type Systems (2008) by VectorLock on Friday May 03, 2019 @05:23PM (#19822423)
"Dynamic types are, at their core, there to remove the incredible tedium of things like generics or templated types."
Re:What to Know Before Debating Type Systems (2008) by jimmaswell on Friday May 03, 2019 @06:12PM (#19822730)
I've never felt like templated types or generics are tedious.
Re:What to Know Before Debating Type Systems (2008) by viraptor on Friday May 03, 2019 @06:49PM (#19822959)
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;
    }
Re:What to Know Before Debating Type Systems (2008) by dvlsg on Friday May 03, 2019 @06:57PM (#19823009)
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.

Re:What to Know Before Debating Type Systems (2008) by jimmaswell on Friday May 03, 2019 @09:12PM (#19823627)
Type erasure was one of the worst decisions in Java, yeah. Generics and working with types in general is great in C#.
Re:What to Know Before Debating Type Systems (2008) by zzygan on Friday May 03, 2019 @09:30PM (#19823696)
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
Re:What to Know Before Debating Type Systems (2008) by jimmaswell on Friday May 03, 2019 @11:28PM (#19824240)
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.

Re:What to Know Before Debating Type Systems (2008) by lazulicurio on Saturday May 04, 2019 @03:07AM (#19824935)
> 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.

Re:What to Know Before Debating Type Systems (2008) by jimmaswell on Saturday May 04, 2019 @12:00PM (#19827250)
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.
Re:What to Know Before Debating Type Systems (2008) by lazulicurio on Saturday May 04, 2019 @03:04PM (#19828507)
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.
Re:What to Know Before Debating Type Systems (2008) by jimmaswell on Saturday May 04, 2019 @05:34PM (#19829525)
You can cast to plain IList and it works as expected. You can even use Add on it.

https://dotnetfiddle.net/jcjchk

Re:What to Know Before Debating Type Systems (2008) by lazulicurio on Sunday May 05, 2019 @03:16PM (#19834434)
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.
Re:What to Know Before Debating Type Systems (2008) by mruts on Friday May 03, 2019 @11:07PM (#19824139)
Could you elaborate? How does type erasure relate to HKT?
Re:What to Know Before Debating Type Systems (2008) by viraptor on Saturday May 04, 2019 @12:46AM (#19824517)
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.

Re:What to Know Before Debating Type Systems (2008) by zzygan on Saturday May 04, 2019 @04:16AM (#19825154)
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

Re:What to Know Before Debating Type Systems (2008) by draw_down on Friday May 03, 2019 @04:11PM (#19821834)
> ... “dynamic types” are, at their core, there to make unit testing less tedious, and are a tool for finding bugs.

I don't think this is a good description of dynamic typing. I'd probably go with something more like, dynamic typing is a way to defer until runtime typing aspects of the program's implementation. I suppose dynamic typing does make unit testing easier, among other things, but it feels wrong to say it's "for" that. A car is for getting one or more people from point A to B. It also has a radio, but a car is not "for" listening to the radio.

Re:What to Know Before Debating Type Systems (2008) by naasking on Friday May 03, 2019 @04:51PM (#19822162)
> I suppose dynamic typing does make unit testing easier, among other things, but it feels wrong to say it's "for" that.

The summary is trying to say that that's dynamic typing's primary advantage. Any other advantage you'd care to ascribe to dynamic typing is not intrinsic to dynamic typing itself.

Re:What to Know Before Debating Type Systems (2008) by ridiculous_fish on Friday May 03, 2019 @05:06PM (#19822280)
The whole article seems concerned with the testability and bug-finding nature of types. But the main strength of dynamic types is the ability to defer decisions until runtime.

JS isn't dynamically typed to make testing easier. JS uses dynamic types because you couldn't build the web any other way.

Re:What to Know Before Debating Type Systems (2008) by naasking on Friday May 03, 2019 @05:59PM (#19822661)
> But the main strength of dynamic types is the ability to defer decisions until runtime.

That's not a strength. Deferring until runtime only that which must be deferred is a strength, but that's not one exhibited by dynamically typed languages. It is one that's available to statically typed languages though, like C# and now even Haskell has a deferred typing mode.

> JS uses dynamic types because you couldn't build the web any other way.

That's patently false. The whole engine running every browser is statically typed. There are libraries for working with the full DOM in HTML documents for Java, C# and other typed languages.

Re:What to Know Before Debating Type Systems (2008) by ridiculous_fish on Friday May 03, 2019 @07:03PM (#19823037)
Obviously the ability to defer decisions to runtime is a strength - how could you possibly dispute that?

And yes statically typed languages have this strength if they use dynamic types. The article's point is that static and dynamic types are fundamentally unrelated to each other. Many languages can and do use both.

When you make a web page you have no idea what "only must" be deferred. There's no way to enforce that the JS you write today will be statically compatible with the libraries and browsers that it touches tomorrow. That's why JS uses dynamic types.

> That's patently false. The whole engine running every browser is statically typed

My point is not about building web browsers, it is about building the web. The web has JS which must coexist with arbitrary other JS, running on many different browsers with many more versions. How could you possibly build this without dynamic typing?

Re:What to Know Before Debating Type Systems (2008) by naasking on Friday May 03, 2019 @09:35PM (#19823715)
> The article's point is that static and dynamic types are fundamentally unrelated to each other

Not unrelated. You can embed dynamic types into a statically typed language, but not vice versa. Formerly dynamically typed languages that pull in static types, like Racket or TypeScript, become statically typed languages with embedded dynamic types.

> There's no way to enforce that the JS you write today will be statically compatible with the libraries and browsers that it touches tomorrow

This has nothing to do with dynamic types but with standardisation. C# is a language that is considerably different from its first release, and yet v1.0 C# still compiles on the latest compiler. The converse is not true, for either JS or C#. Dynamic types don't help with this problem.

> The web has JS which must coexist with arbitrary other JS, running on many different browsers with many more versions. How could you possibly build this without dynamic typing?

How do all the arbitrary programs on your computer coexist? The programs that interact do so via protocols or standard interfaces, and the ones that don't interact are isolated. This is no different than any other software.

Re:What to Know Before Debating Type Systems (2008) by ridiculous_fish on Saturday May 04, 2019 @12:50AM (#19824529)
> Formerly dynamically typed languages that pull in static types, like Racket or TypeScript, become statically typed languages with embedded dynamic types.

These languages are not "formerly dynamically typed." These languages are fully dynamically typed. Dynamic typing does not mean the absence of static types! That's the main point of the article.

I use and love statically typed languages. Dynamic types are a "yes and", enabling new things. ObjC and TypeScript are examples of languages with static and dynamic types.

> C# is a language that is considerably different from its first release, and yet v1.0 C# still compiles on the latest compiler. The converse is not true, for either JS or C#. Dynamic types don't help with this problem.

Actually dynamic types help enormously with this problem. They enable testing for the presence of features at runtime, and conditionally invoking code that otherwise could not type check.

Consider for example preventing event propagation in JS. This varies by browser so you might write:

    if (event.preventDefault) event.preventDefault();
dynamically checking for the presence of a field, and then invoking it as a function. This is where dynamic types shine.

You can write this in C# or Java using reflection, because these languages have dynamic types. You can't write this in languages without dynamic types.

> How do all the arbitrary programs on your computer coexist? The programs that interact do so via protocols or standard interfaces

Every program on my computer is a conversation between the application code, the system libraries, and plugins. The browser I am using to type this dynamically interrogates the classes that it uses to discover their features, and conditionally invoke code. Example [1] - notice how this statically typed code is making a dynamic type query, illustrating that these concepts are completely compatible.

My computer's programs rely on dynamic types. That's how they retain compatibility across different versions, and it's how the OS vendor keeps the programs working across system updates.

1: https://chromium.googlesource.com/chromium/src.git/+/62.0.31...

Re:What to Know Before Debating Type Systems (2008) by naasking on Saturday May 04, 2019 @09:32AM (#19826330)
> These languages are not "formerly dynamically typed." These languages are fully dynamically typed. Dynamic typing does not mean the absence of static types!

No, dynamically typed means the program has only one type: the universal value.

> They enable testing for the presence of features at runtime, and conditionally invoking code that otherwise could not type check. [...] You can't write this in languages without dynamic types.

That's incorrect. Extensible idioms don't look the same as they do in dynamically typed languages, but looking the same is immaterial. The same sort of behavioral extensibility is achievable with static typing without reflection, for instance, as found in the Yi editor [1]. Once again, it's about protocols and interfaces.

> Example [1] - notice how this statically typed code is making a dynamic type query, illustrating that these concepts are completely compatible.

That is merely one way to do it

> My computer's programs rely on dynamic types. That's how they retain compatibility across different versions, and it's how the OS vendor keeps the programs working across system updates.

That's not dynamic typing, compatibility is the advantage of standardized protocols and interfaces.

[1] https://yi-editor.github.io/

Re:What to Know Before Debating Type Systems (2008) by gpderetta on Saturday May 04, 2019 @02:08PM (#19828132)
>Consider for example preventing event propagation in JS. This varies by browser so you might write: > > if (event.preventDefault)

FWIW, that sort of field existence check (and much more) can be done fully at compile time in many mainstream programming languages.

Re:What to Know Before Debating Type Systems (2008) by dllthomas on Friday May 03, 2019 @07:05PM (#19823046)
> dynamic typing is a way to defer until runtime typing aspects of the program's implementation

That's more of a "how", where the bit you quoted seemed to be speaking to "why", IMO.