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

Type checked against what, if a variable doesn't have a type?

There are contexts in which two values are involves, where we can at least check that the types are matching (or reasonably compatible), like (a + b). JS is a massive failure in that regard, too, and there are dynamic languages that do it far better - e.g. in Python, ("1" + 2) is a runtime type error, not 3.

But in the context of this thread, I feel that's not what we're talking about. We're really talking about contracts - and contracts require typed bindings (variables, function arguments etc), not just typed values. Which means that they do require static type annotations. As we've discussed in another subthread, those annotations might be checked dynamically - but they still have to be declared statically by the coder, which makes the type system effectively static from their perspective.

To put it differently: if you require types to be declared explicitly, there's no reason to not check them statically. Dynamic checking of static types really only makes sense for gradual typing systems, where code with static type annotations might be called from some non-annotated code, and you want it to be possible without forcing static typing on the caller. At that point, yes, you can have a dynamic type check in the callee, which ensures that if code without type annotations doesn't actually get the types right, things fail fast at the static/dynamic typing boundary, instead of allowing it to propagate into the statically typed code (as is the case in e.g. TS today).




> if you require types to be declared explicitly, there's no reason to not check them statically.

I think some of this thread is suffering from confusing terms so, my entire point is this:

There is no native way in javascript to say that the first argument of function foo must be an instance of class Bar (which in JS could be a string or an array or some custom object or even a DOM element - everything is an object and thus has a 'class').

The common response is "use typescript" which means you write the code with argument type declarations, and then compile to javascript. This (in theory) means any code you've written in the project in TS which calls our foo() function, will warn/error if the first argument isn't an instance of class Bar.

But, and this is the problem: it's not enforced by javascript, it's "enforced" (for whatever definition of enforced typescript uses) by the TS compiler.

So if I then use the compiled JS of function foo() and call it from native JS (i.e. not compiled by TS) - it won't tell me I have the wrong type.

THAT is my issue.


Yes, I understand that. My point was that it's not really dynamic typing at that point anymore. It's kinda like C#, where you do have "dynamic", but there are static type annotations that code utilizing "dynamic" can validate against. At that point, I'd say that it's no longer a dynamic language in conventional sense.

Getting back to your issue - it's a pragmatic decision for TS, because enforcing its type system efficiently is virtually impossible on top of the JS runtime type system, when you consider how it has to work. It sounds like simple, obvious check for trivial cases, like if I annotate a function argument to be an number or a string. But what if it's an interface? At that point, the runtime check must ensure that 1) it's an object, 2) it has all the members listed in the interface, and 2) they have the corresponding types. If they are themselves interfaces, this becomes recursive. If they're arrays or maps, then this has to be done for every element. An array of arrays is O(N^2) already!

To check it efficiently, you need to have proper runtime type tags - an array has to know that it's an array of number, not just an array. Then the runtime checker can just query that, like it does in Java when you, say, downcast Object to int[]. But TS has to work on top of JS runtime, so any such runtime type tagging would manifest as visible artifacts in JS; and TS is intentionally designed to be "invisible" from JS interop perspective.

If we want quality strong typing that works properly with cross-language interop for the web, we need to throw away the JS runtimes entirely (it would be a good idea in any case - it's an atrocious object and memory model for anything other than JS itself), and replace them with something saner.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: