DEV Community

Discussion on: JavaScript is not an untyped language

 
miguelmj profile image
MiguelMJ • Edited

Types are not necessarily inferred at compile time, in fact that's what dynamic typing means.

Object-oriented languages are perfectly valid from type theory perspective and inheritance has been formalized more than once [a][b 6.1].

Expressions can have types attached in the sense that they are evaluated to a value, which has type. But when that evaluation doesn't depend on the structure of the parsed phrase, then the expression hasn't a type per-se (3 + 4 has a value a + b no). Edit: Function overloading is a perfect example for this.

A similar discussion on this one.

Thread Thread
 
peerreynders profile image
peerreynders

If you have an expression f(a) and you know that a : A and f : A -> B then you know that the result type of that expression is B.

OK, using that notation A and B simply look like parameterized types which simply express type constraints, not full-blown types.

You can compute the type of any expression at compile-time simply by looking at its components.

The thing is there is no "compile-time" with JavaScript. It's V8 that uses just-in-time compilation (Sparkplug, TurboFan) but that's just an implementation detail.

But that's not what people talk about when they say a language is typed or untyped, because it'd be a pointless distinction.

After a quick online search I have to come to the conclusion that 'untyped' is a pointless term just like 'weakly typed' or 'strongly typed'. Without a clear definition people just assume that their interpretation is the correct one, leading to endless, pointless debates.

Javascript has exactly one type: "any".

Can't agree there.

any is simply TypeScript's way of throwing its arms up in the air when it doesn't know what is going on. JavaScript has clearly documented types:

  • primitive values (which are all immutable): Boolean, Null, Undefined, Number, BigInt, String, Symbol
  • objects (including arrays)

(null was introduced as a primitive value to represent the absence of an object for a Java interop bridge—it really shouldn't exist)

An actual any type would be something like a Visual Basic Variant and JavaScript doesn't have anything like that.

All values in JavaScript have a type. The issue with dynamic typing is that the resulting type of any expression or (variable) name is only computed at runtime rather than statically analysed at design time.

Conceptually everything in JavaScript it late bound however for the sake of performance V8 may JIT some of the unproductive late binding away when it can get away with it.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

The thing is there is no "compile-time" with JavaScript. It's V8 that uses just-in-time compilation (Sparkplug, TurboFan) but that's just an implementation detail.

That's not entirely true; almost all modern scripting languages have some sort of compilation step that turns the source code into some sort of (virtual) machine code.

I'm not aware of any language that's directly interpreted and has a proper type system, but if such a thing existed, you could just replace "compile time" with "parse time" and the statement would still be work.

After a quick online search I have to come to the conclusion that 'untyped' is a pointless term just like 'weakly typed' or 'strongly typed'. Without a clear definition people just assume that their interpretation is the correct one, leading to endless, pointless debates.

I think that's kind of what's happening here. But I still think my statement holds true: there's not much of a point in distinguishing "typed" and "untyped" languages when "typed" just means the VM tags its values and keeps track of their "type" at runtime. By that definition, untyped languages just don't make sense unless we're talking about DSLs or esolangs.

JavaScript has clearly documented types

Depends on how you define types. Using a loose definition, that may be true. But then, once again, you end up at every language in existence being typed, so the whole categorisation becomes pointless.

In a stricter sense, no, JavaScript has exactly one type. Whether you call this "any" or something else doesn't really matter, but since "any" is what most languages use for a union of all types, that's what I called it. (Some might say union types shouldn't exist at all, and to be honest, I'd even agree with that to some extent.)

All values in JavaScript have a type

Values. Don't. Have. Types. That's just not what types, strictly speaking, in the sense of type theory, are. And again, I'm okay with calling them "types" in a broader sense, but then we end up back at all languages are always typed. I call them types too, when the context makes it clear what I'm talking about, but really, they're just tagged values. You can't type-check a JS program. Or rather, you can, and it's always valid, because there is only one type.


So in summary: There is two ways we can define "type".

In the strict sense, types are decided during compile (or parse) time, and languages are either typed or untyped. Untyped languages can technically be considered typed languages where every expression has the same type.

In the broader sense, types are just information about what kind of thing a value represents, and can be handled either by compile-time type checks or by run-time value tagging. In this sense, all languages are typed, but some are statically typed, while others are dynamically typed.

And lastly: Anybody arguing in good faith will normally use "typed" and "untyped" only in the context of the first definition, because that's the only way for the definition to make sense.

Calling JavaScript a "typed" language according to the second definition is technically true, but a) adds no value whatsoever and b) should be accompanied by an explanation pointing out that this definition is being used.


So yea, Javascript is an untyped language. It's also dynamically typed. But it definitely isn't typed.

Thread Thread
 
peerreynders profile image
peerreynders • Edited

all modern scripting languages have some sort of compilation step that turns the source code into some sort of (virtual) machine code.

That really is just an opportunistic optimization for dynamic languages that should have no bearing on the type system.

you could just replace "compile time" with "parse time" and the statement would still be work.

TypeScript cannot safely type all of JavaScript. That is evidence that there are circumstances where the exact types only emerge at runtime.

In fact statically typed languages implement polymorphism with late binding, so they don't even know the exact type at "compile time", only the type constraints that have to be satisfied at runtime.

there's not much of a point in distinguishing "typed" and "untyped" languages

For me the discussion revolves around the common misconception that dynamically typed languages do not have types; that only statically typed languages have types. There's the common oversimplification that the lack of type declarations implies the absence of types which is simply not true. (The illusion that static typing automatically implies total type safety is a separate discussion).

Depends on how you define types.

I'm not familiar with a definition of types where JavaScript's data types would not classify as types.

JavaScript has exactly one type. Whether you call this "any" or something else doesn't really matter,

any is one of TypeScripts two top types.

The top types any and unknown in TypeScript

In many ways unknown is the more accurate top type. Just because a type is unknown at design time doesn't imply that a value won't have an exact type (which could be the wrong type for what you are trying to do) at runtime.

I still don't see that the argument that one of TypeScript's top types is JavaScript's only, singular type holds any water.

(Some might say union types shouldn't exist at all, and to be honest, I'd even agree with that to some extent.)

Oh boy … sum types

Values. Don't. Have. Types.

Is this what you are talking about: "You can say that 'Type' is the data type of the expression used at compile time."

It would have been a lot faster to state that types only exist at compile time by virtue of which any language that isn't statically analysed and compiled is automatically 'untyped'.

The core of the discussion really is that those ones and zeros exhibit behaviour that is consistent with being "typed" by virtue of the rules enforced by the runtime engine.

The confusion wasn't about whether or not JavaScript is compiled (it depends).

types are decided during compile (or parse) time, and languages are either typed or untyped. Untyped languages can technically be considered typed languages where every expression has the same type.

There it is …

Anybody arguing in good faith will normally use "typed" and "untyped" only in the context of the first definition

Again, really? If you are a pure mathematician perhaps.

But as software developers and engineers we are more interested in the runtime behaviour even if we like to have some compile time assurances.

Calling JavaScript a "typed" language according to the second definition is technically true

If I was given that for review I would edit it to:

"JavaScript has types".

Stating "JavaScript is typed" sets certain expectations it cannot live up to. The issue is that "JavaScript is untyped" implies the absence of "type-equivalent behaviour" at runtime which is not true.

So yea, Javascript is an untyped language. It's also dynamically typed.

JavaScript is dynamically typed. The term "dynamically typed" implies that types can in fact exist at runtime. I'm not touching "untyped" with a ten foot pole.

Thanks for elaborating.

Thread Thread
 
miguelmj profile image
MiguelMJ

@darkwiiplayer could you please refer me to where hve you learned about types? The books on PLT I've read all consider types semantic information. I understand you don't agree with that definition, so I would appreciate if you could share with me where are you getting yours from. Thanks for your elaborated responses, truly!

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

If it's the one I remember, then this gives a pretty good introduction to the concept.

I'm also aware that the HoTT book would be a much better source on this, but alas, that's still on my reading list; but I still wanted to mention it.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

TypeScript cannot safely type all of JavaScript. That is evidence that there are circumstances where the exact types only emerge at runtime.

Yes, which is why I've lately started agreeing with the idea that union types (and other concepts of set theory applied to type theory) might just be a dumb idea.

For me the discussion revolves around the common misconception that dynamically typed languages do not have types; that only statically typed languages have types.

Then you're arguing based on the broader idea of what types are, which, as I pointed out, means that all languages do, to some extent, have types, so the whole concept of "typed" language is pointless, as there is no real example of an actual "untyped" language by that definition, other than possibly the occasional esolang.

I'm not familiar with a definition of types where JavaScript's data types would not classify as types.

An example would be the one found on wikipedia:

A "type" in type theory has a role similar to a "type" in a programming language: it dictates the operations that can be performed on a term and, for variables, the possible values it might be replaced with.

Or from the introduction of the paper I linked above

Types are not sets. Types are a bit like sets, but types give syntactic information, e.g. [maths omitted] whereas sets give semantic information, e.g. [more maths omitted]

any is one of TypeScripts two top types.

any is just the unfortunate consequence of a typed language interacting with an untyped language and having to somehow figure out how to transfer untyped data into its type system. It also leads back into what I said above: Union types bad.

I still don't see that the argument that one of TypeScript's top types is JavaScript's only, singular type holds any water.

I find it plainly obvious. let foo What is the type of foo? Regardless of what you want to call it, whether "any" or "unknown", the fact remains: It's the one and only type that all expressions in javascript can have. There is no imaginable scenario where foo = bar would give you a syntax error because the types of foo and bar do not match.

It would have been a lot faster to state that types only exist at compile time by virtue of which any language that isn't statically analysed and compiled is automatically 'untyped'.

That is what types are. More precisely, I've been arguing this whole time, and I've said this repeatedly, that this is the stricter of two definitions that are commonly used in programming. It's the definition we get from type theory, which is still the predominant definition of "type" when talking about functional languages.

My two points here are:

  1. This is the only definition of the two that needs to be considered, as the word "typed" holds no value under the other, broader definition.

  2. According to this definition, JavaScript is, no matter how you look at it, an untyped language.

The core of the discussion really is that those ones and zeros exhibit behaviour that is consistent with being "typed" by virtue of the rules enforced by the runtime engine.

And as per 1., this applies to all programming languages, therefore all programming languages are typed, so we might as well never use that word again. Except most people usually understand that when distinguishing between typed and untyped languages, we're specifically talking about the kind of types we get from type theory, which can be statically analysed, where we can determine the type of an expression without running into the halting problem. And by that definition, see 2.

The confusion wasn't about whether or not JavaScript is compiled (it depends).

Again, this is a minor issue in phrasing. I say "compile time" because that's when most languages, including most implementations of JavaScript, would have a chance to do static analysis before running the code. It would have been more correct to phrase it as that: static analysis, but as I pointed out, that's a minor nitpick and easily fixed by replacing a single word.

Again, really? If you are a pure mathematician perhaps.

Again, what's the point? Sure, you can use the word "typed" in the sense that values can be classified at run-time, but at that point you're just not saying anything. It's like calling water wet. It's not wrong, but it just adds no value.

If someone tells me "That desk looks really solid", my first response (usually) won't be "Of course, did you expect it to be liquid? All desks are solid, duh!". Yes, that would be a completely valid way to interpret the sentence. But in context one just rules it out because it's obvious, so we assume the word must mean something else in this case.

This is why I don't get how someone, arguing in good faith, can point out that JavaScript is a typed language. Yes, it has values that do things, I knew that.

The issue is that "JavaScript is untyped" implies the absence of "type-equivalent behaviour" at runtime which is not true.

Is there any language where this isn't the case? Outside the realm of possibly some niche DSLs or esolangs that people came up with for fun, is there any language that neither has a static type system, nor some sort of distinguishing different kinds of values at runtime? Even languages that cast types around whenever remotely possible often offer some way of querying the type of a value.

So yea, back to 2, no programming language is untyped. By establishing this, we've gained absolutely nothing. Just like how pointing out that JavaScript is statically typed, because it has a single type that represents a tagged value doesn't really help us either.

JavaScript is dynamically typed. The term "dynamically typed" implies that types can in fact exist at runtime.

Yes. In so far as the word "solid" implies that a desk can be made of water. The term "dynamically typed" only underlines my point: There are two definitions of types being conflated here. And by one of them, all languages are typed, so we need to distinguish how they are typed.


All in all, I really feel like I need to repeat this core point:

  1. There are two different definitions of what a "type" is.

  2. The distinction between "typed" and "untyped" only makes sense with one definition.

  3. The distinction between "dynamically" and "statically" typed only exists with the other definition.

Using the terminology of one with the definition of the other is pointless, confusing and dumb.

And lastly:

  1. JavaScript is both typed and untyped, depending on what definition you use.

Neither claim is wrong, but only one conveys any actual information.

Thread Thread
 
peerreynders profile image
peerreynders

Thank You for your explanation which establishes the context from which the statement "JavaScript is untyped" makes sense.

This is why I don't get how someone, arguing in good faith, can point out that JavaScript is a typed language.

My interpretation of this article is that it is trying to address the case where the statement "JavaScript is untyped" is made while the not having the strict definition of "types" as you present it (and people reading and running with it).

I personally stick with statically and dynamically typed for practical reasons but all too often come across dubious uses of "weakly typed" and "strongly typed" where "untyped" isn't being used to state "without static analysis" but to imply so fundamentally unreliable, it might as well just be operating on a sea of strings.

There seems to be an ongoing oversimplification

  • statically analysed = safe and correct (e.g. type safety)
  • dynamically typed = absolute garbage

My position is that I am constantly thinking in "types" even when working with a dynamically typed language.

Thread Thread
 
miguelmj profile image
MiguelMJ

Thanks for the link. I'll take my time to contrast that with my own and try to contextualize how and when the each terms appear. Thanks once more for the discussion!