<p>I noticed in JavaScript and Lua, <em>'types'</em> i.e., those returned by <code>typeof()</code>/<code>type()</code> are just identified by strings. As such we see code such as:</p>
<pre><code>if (typeof(x) != &quot;number&quot;) { /* ... */ }
</code></pre>
<p>Why would one do this instead of having specific objects that refer to types? <code>Number</code> as a constructor already exists in JavaScript so why not this instead?</p>
<pre><code>if (typeof(x) != Number) { /* ... */ }
</code></pre>
<p>What are the reasons to use a string to identify types, instead of having a metatype (a <em>'type'</em> type), or simply returning an object such as a constructor function?</p>

<types><strings><dynamic-typing><javascript><lua>
Why do many dynamically typed languages identify types with strings?
CC BY-SA 4.0
2023-06-03T20:22:06.773Z
At least in JavaScript, there’s a difference between primitive numbers and number objects, so if `typeof` returned the constructor it wouldn’t differentiate those.
Bbrk24
CC BY-SA 4.0
2023-06-03T20:24:01.257Z
@Bbrk24 Then it could return `Object` for number objects, and `Number` for number primitives.
CPlus
<p>For the scripting languages that do this, strings are one of the few built-in types and have a major advantage in being printable and introspectable. This is particularly valuable for languages meant to be embedded in other systems, like both Lua and JavaScript, where just getting a string displayed <em>somewhere</em> is a critical debugging step. That is a key usage of <code>typeof</code>/<code>type()</code>: my code is breaking, so tell me, what kind of value did I actually get at this point? This is also the case for PHP, and for R as well — they're really <em>debugging</em> tools more than anything else.</p>
<p>Adding additional meta-type objects is a pretty significant addition for fairly little benefit in that case, but when they do it would arguably be better to reverse the process anyway: expose a static <code>Number.isNumber(x)</code> rather than having people write <code>typeof x == &quot;number&quot;</code> at all. The ability to use the type identification for type-based branching is more of a side effect than a goal.</p>
<p>However, I'm not sure I agree that &quot;so many dynamically-typed languages&quot; do this. Other than the ones listed, widespread dynamically-typed languages designed as programming languages mostly <em>don't</em> seem to do this. Python and Ruby expose class objects instead, for example, and Tcl doesn't expose this at all, while in Perl it doesn't really even make sense as a question (perhaps <code>ref()</code> counts?).</p>
<p>On the other hand, if I'm building one I'm probably putting in strings before I consider reflective behaviour, so they have the advantage of availability. Many little languages just don't have anything beyond simple types that could represent this information. Adding something to describe a value to me for debugging early on in development and having it stick around is very plausible.</p>
<hr />
<p>Let's take the JavaScript case as a working example. To recap, the <code>typeof</code> operator returns one of the strings &quot;string&quot;, &quot;number&quot;, &quot;function&quot;, &quot;object&quot;, &quot;boolean&quot;, &quot;object&quot;, &quot;undefined&quot;, (new) &quot;symbol&quot;, (newer) &quot;bigint&quot;, or another host-defined string (not attested in practice). All non-primitive values return &quot;object&quot;, except for functions; symbols are primitive types despite having reference identity and no literals. There are also boxed types String, Number, Boolean, and BigInt, which autounbox as needed; <code>typeof new Number(1)</code> returns &quot;object&quot;. There is no constructor for the undefined type. <code>typeof</code> was introduced during the LiveConnect era of Netscape 3, as part of tighter connections with Java, and <em>isn't</em> part of the original &quot;ten days in May&quot;.</p>
<p>A significant advantage of returning a string for an interactive scripting language like this is that the value is a string, so while debugging you can print it, or (more likely in 1996) <code>alert(typeof x)</code> it.</p>
<p>The boxed <code>Number</code> constructor is a function, as all JavaScript constructors are. If <code>typeof</code> returned that instead of a string, <code>alert(typeof x)</code> would display</p>
<pre class="lang-none prettyprint-override"><code>function Number() {
    [native code]
}
</code></pre>
<p>because that is how native functions stringify. While this is eventually understandable, probably, it's definitely worse. This is a concrete example of where a direct string is more helpful, although of course the language could <em>also</em> have decided to specify <code>toString()</code> on this function to return something more useful, and perhaps would have done if it were expected to be used in this way.</p>
<p>JavaScript does provide a way of getting more useful information for reference types, by way of the <code>constructor</code> property on <code>new</code>-created objects, and <code>Object.getPrototypeOf</code> in the library. These would all be described just as &quot;object&quot; by <code>typeof</code>, but real inspectable objects are given by these operations. A modern JavaScript might well <em>only</em> have these, and no primitive types (for that matter, the <em>original</em> JavaScript probably would have done given more time and less pressure from Sun).</p>
<p>Lua has essentially the same set of types, where &quot;object&quot; is spelled &quot;table&quot;. It has no real concept of data type beyond that, so adding a substantive meta-type object would have been a pretty big addition for very little gain. There's certainly an argument that a string is <em>less good</em> than some meta-object, and (as ever) that JavaScript got it wrong before cementing it as unchangeable.</p>
<p>A from-scratch design for JavaScript today might well make a different choice, though I suspect Lua wouldn't. If you're making a new language and you have support for a type of value that could represent these types better, I'd probably use it. If it's just for little embedded scripts and you only have a few core data types, then <em>if</em> you need to expose a <code>typeof</code> operation then strings seem like the clear choice.</p>

CC BY-SA 4.0
2023-06-04T00:27:50.807Z
2023-06-04T00:27:50.807Z
Michael Homer
CC BY-SA 4.0
2023-06-04T12:03:24.293Z
Also consider that when represented as strings, future types can easily be added. If each type is represented by a reserved word, how can any new type be added without possibly conflicting with existing user code that shares the same namespace?
Ray Butterworth
# Why do many dynamically typed languages identify types with strings?
Posted by: username_0 on 2023-06-03
I noticed in JavaScript and Lua, 'types' i.e., those returned by typeof()/type() are just identified by strings. As such we see code such as:
if (typeof(x) != "number") { /* ... */ }

Why would one do this instead of having specific objects that refer to types? Number as a constructor already exists in JavaScript so why not this instead?
if (typeof(x) != Number) { /* ... */ }

What are the reasons to use a string to identify types, instead of having a metatype (a 'type' type), or simply returning an object such as a constructor function?
**Tags:** types strings dynamic-typing javascript lua
> **Comments:**
> **username_1**: At least in JavaScript, there’s a difference between primitive numbers and number objects, so if `typeof` returned the constructor it wouldn’t differentiate those.  
> **username_0**: @Bbrk24 Then it could return `Object` for number objects, and `Number` for number primitives.  
---
## 1 answers
### Answer by username_2 on 2023-06-04. Score: 8 | Accepted answer
For the scripting languages that do this, strings are one of the few built-in types and have a major advantage in being printable and introspectable. This is particularly valuable for languages meant to be embedded in other systems, like both Lua and JavaScript, where just getting a string displayed somewhere is a critical debugging step. That is a key usage of typeof/type(): my code is breaking, so tell me, what kind of value did I actually get at this point? This is also the case for PHP, and for R as well — they're really debugging tools more than anything else.
Adding additional meta-type objects is a pretty significant addition for fairly little benefit in that case, but when they do it would arguably be better to reverse the process anyway: expose a static Number.isNumber(x) rather than having people write typeof x == "number" at all. The ability to use the type identification for type-based branching is more of a side effect than a goal.
However, I'm not sure I agree that "so many dynamically-typed languages" do this. Other than the ones listed, widespread dynamically-typed languages designed as programming languages mostly don't seem to do this. Python and Ruby expose class objects instead, for example, and Tcl doesn't expose this at all, while in Perl it doesn't really even make sense as a question (perhaps ref() counts?).
On the other hand, if I'm building one I'm probably putting in strings before I consider reflective behaviour, so they have the advantage of availability. Many little languages just don't have anything beyond simple types that could represent this information. Adding something to describe a value to me for debugging early on in development and having it stick around is very plausible.

Let's take the JavaScript case as a working example. To recap, the typeof operator returns one of the strings "string", "number", "function", "object", "boolean", "object", "undefined", (new) "symbol", (newer) "bigint", or another host-defined string (not attested in practice). All non-primitive values return "object", except for functions; symbols are primitive types despite having reference identity and no literals. There are also boxed types String, Number, Boolean, and BigInt, which autounbox as needed; typeof new Number(1) returns "object". There is no constructor for the undefined type. typeof was introduced during the LiveConnect era of Netscape 3, as part of tighter connections with Java, and isn't part of the original "ten days in May".
A significant advantage of returning a string for an interactive scripting language like this is that the value is a string, so while debugging you can print it, or (more likely in 1996) alert(typeof x) it.
The boxed Number constructor is a function, as all JavaScript constructors are. If typeof returned that instead of a string, alert(typeof x) would display
function Number() {
    [native code]
}

because that is how native functions stringify. While this is eventually understandable, probably, it's definitely worse. This is a concrete example of where a direct string is more helpful, although of course the language could also have decided to specify toString() on this function to return something more useful, and perhaps would have done if it were expected to be used in this way.
JavaScript does provide a way of getting more useful information for reference types, by way of the constructor property on new-created objects, and Object.getPrototypeOf in the library. These would all be described just as "object" by typeof, but real inspectable objects are given by these operations. A modern JavaScript might well only have these, and no primitive types (for that matter, the original JavaScript probably would have done given more time and less pressure from Sun).
Lua has essentially the same set of types, where "object" is spelled "table". It has no real concept of data type beyond that, so adding a substantive meta-type object would have been a pretty big addition for very little gain. There's certainly an argument that a string is less good than some meta-object, and (as ever) that JavaScript got it wrong before cementing it as unchangeable.
A from-scratch design for JavaScript today might well make a different choice, though I suspect Lua wouldn't. If you're making a new language and you have support for a type of value that could represent these types better, I'd probably use it. If it's just for little embedded scripts and you only have a few core data types, then if you need to expose a typeof operation then strings seem like the clear choice.
> **Comments:**
> **username_3** (2023-06-04): Also consider that when represented as strings, future types can easily be added. If each type is represented by a reserved word, how can any new type be added without possibly conflicting with existing user code that shares the same namespace?  
---
