One of the best ways to get people to support optional typing in dynamic languages is to make sure their tools can read those types and provide metadata.
Program verification is cool, but enabling "intellisense" on a hash is even cooler.
Indeed. I'm hoping the IDE support will include emacs - it can already do loads of cool things connected to nrepl, but completion on a hash would be amazing.
I still don't think this is worth supporting if you don't use Clojure. As far as dynamic languages go, I already use Racket quite a bit and as mentioned I can just use Typed Racket if I want, or I can use Racket's excellent contract system for some things (sparingly if I need good performance). Also I doubt it will catch on in the Python community, which is hostile to this sort of thing. JavaScript is perhaps a good use for it but there are already typed languages that run in the browser.
FWIW I've been pushing Typed Clojure in interesting directions that can be directly applied back to Typed Racket. The implementations are so similar that there is good potential for cross pollination.
Typed Racket and Typed Clojure are major sources of inspiration/reference for typed versions of JavaScript like TypeScript and possibly future versions of EcmaScript.
AFAIK Typescript is level 1 gradual typing. Typed Clojure is also level 1, but I'm aiming for level 3.
I guess Typed Clojure is more powerful than Typescript in a few ways, but it's more about how well the type system fits the language. I've never used Typescript, but it seems to fit nicely, with interesting tradeoffs.
Based on my experience, dynamic languages without optional typing make large scale enterprise development unbearable.
Sure, one should be writing unit tests, but in the enterprise context those tests rarely do exist, or if they do, either don't test what they should or are so complex that invalidate any re-factoring taking place.
Do you have any experience with the inverse statement? That is, have you had a good experience with optional types in an enterprise context?
I'm curious how many runtime errors persist due to the optionality of the type system. Perhaps code standards requiring all "library" code to be typed would be a good balance.
Here the parameter x is an int or float, and so is the return type.
It doesn't currently let you compose types, but that wouldn't be too difficult to add, e.g. {str:int} could mean a dictionary whose keys are strings and values are integers.
That's okay, but that doesn't seem to help much to verify your type correctness before runtime, which seems to me to be a big part of the benefit of type checking. Also, what you'd really want is something that implements type variables like:
@typ[A implements *](A, ret=A)
def square(x):
return x * x
But I don't know how you'd do that in Python.
BTW, your printargs looks pretty cool! I might just makes something like that for JS...
This guy is a little too souped on optional type-checking. This has existed in erlang for years, in the form of dialyzer (which allows for compile time validation of complex nested data structures), and in any dynamic language a good developer is using pre-checks & post-checks (in the case of js) or a combination of tagged values and pattern matching to ensure type-checking at runtime.
It's a nice feature, but calling it "one of the biggest advancements to dynamic programming languages in the last few decades" is ignorant.
Pre- and post-checks are of course possible, but I've rarely seen them used in practice. More importantly, they can't be used to provide any sort of correctness guarantee, which static typing can.
I'm not sure what you mean by tagged values and pattern matching - I know what those concepts are, but I think you're saying they're widely used by good developers? I have not seen evidence for this.
The reason I call it one of the biggest advancements is that it is actually being used in production, has low overhead (both in cognitive load and performance-wise), and actually handles the complexities of duck-typing. It shows that it is practical. (By contrast, Erlang is sufficiently different to most other dynamic languages, both in use case and semantics, that it is difficult to generalize from Erlang to say Python).
I will tiptoe carefully around the issue you're bringing up and point out that the styles of type checking provided by Dialyzer and Typed Clojure are pretty different.
If this really is what I think it is (a certain reference to a class can never be nil) then I am really excited. It never made sense to me that someone was able to call a function I wrote that really needed instances with nils instead, so I was forced to check and throw in case they did. It's just not clear and it leads to a lot of unnecessary checking or nil pointer exceptions.
Check out cobra, python inspired -- it already helped developers "realize how great optional typing can be in everyday code": http://cobra-language.com/docs/why/
> Typed Clojure is one of the biggest advancements to dynamic programming languages in the last few decades. It shows that you can have the amazing flexibility of a dynamic language, while providing lightweight, optional typing.
I'm sure there have been great advances. But you are showcasing this as if it was a completely new idea, even though PHP has been using it for a long time. Correct me if I'm wrong.
OP here. This is substantially different than what exists in PHP. I tried to hint about this when referencing "nominal" vs "structural" in the piece, but you can just about say "I expect the parameter to be this type" in PHP, which is substantially less powerful than this.
The type system for typed closure is much more powerful and is build on solid PL research. For example, it handles higher order types, union types and has a nifty system for overloading.
Can 100% unit test coverage give you intellisense, real-time warnings, and refactoring capabilities? Nope.
Unit testing is great for verifying that a piece of code works conforms to specification, but typing verifies that you're using a piece of code as expected. Two different things.
Unit test coverage (as much as I enjoy it, since that's how CircleCI makes all its money) is good, but it can't provide the guarantees static type checking can. Each has its place, and neither replaces the other.
Coverage isn't the same as enumeration of all possible modes. 100% test coverage might mean that all of your "wiring" fits together, but with dynamic languages it may not as runtime information may affect your types and break things.
100% enumeration of runtime behaviors is another property, far stronger than any non-dependent static types today, but also exponentially more difficult than 100% test coverage.
Good static types are a cheap way to get probably halfway between those two on a log scale.
[+] [-] brudgers|12 years ago|reply
http://www.eecs.northwestern.edu/~robby/pubs/papers/oopsla20...
[+] [-] ambrosebs|12 years ago|reply
[+] [-] breckinloggins|12 years ago|reply
Program verification is cool, but enabling "intellisense" on a hash is even cooler.
[+] [-] pbiggar|12 years ago|reply
[+] [-] ambrosebs|12 years ago|reply
[+] [-] anaphor|12 years ago|reply
[+] [-] ambrosebs|12 years ago|reply
[+] [-] juandopazo|12 years ago|reply
[+] [-] dribnet|12 years ago|reply
[+] [-] zcrar70|12 years ago|reply
Clojure's type system sounds more powerful than Typescript's though.
[+] [-] ambrosebs|12 years ago|reply
I guess Typed Clojure is more powerful than Typescript in a few ways, but it's more about how well the type system fits the language. I've never used Typescript, but it seems to fit nicely, with interesting tradeoffs.
[+] [-] pjmlp|12 years ago|reply
Based on my experience, dynamic languages without optional typing make large scale enterprise development unbearable.
Sure, one should be writing unit tests, but in the enterprise context those tests rarely do exist, or if they do, either don't test what they should or are so complex that invalidate any re-factoring taking place.
[+] [-] quatrevingts|12 years ago|reply
I'm curious how many runtime errors persist due to the optionality of the type system. Perhaps code standards requiring all "library" code to be typed would be a good balance.
[+] [-] mseebach|12 years ago|reply
http://www.clojure.net/2013/03/14/Typed-Clojure/
[+] [-] cabalamat|12 years ago|reply
Sample:
Here the parameter x is an int or float, and so is the return type.It doesn't currently let you compose types, but that wouldn't be too difficult to add, e.g. {str:int} could mean a dictionary whose keys are strings and values are integers.
[+] [-] acjohnson55|12 years ago|reply
BTW, your printargs looks pretty cool! I might just makes something like that for JS...
[+] [-] wcummings|12 years ago|reply
It's a nice feature, but calling it "one of the biggest advancements to dynamic programming languages in the last few decades" is ignorant.
[+] [-] pbiggar|12 years ago|reply
Pre- and post-checks are of course possible, but I've rarely seen them used in practice. More importantly, they can't be used to provide any sort of correctness guarantee, which static typing can.
I'm not sure what you mean by tagged values and pattern matching - I know what those concepts are, but I think you're saying they're widely used by good developers? I have not seen evidence for this.
The reason I call it one of the biggest advancements is that it is actually being used in production, has low overhead (both in cognitive load and performance-wise), and actually handles the complexities of duck-typing. It shows that it is practical. (By contrast, Erlang is sufficiently different to most other dynamic languages, both in use case and semantics, that it is difficult to generalize from Erlang to say Python).
[+] [-] ambrosebs|12 years ago|reply
[+] [-] draegtun|12 years ago|reply
NB. And I believe Perl6 in certain cases will/can raise compile-time type errors.
[+] [-] dep_b|12 years ago|reply
nil isn’t allowed
If this really is what I think it is (a certain reference to a class can never be nil) then I am really excited. It never made sense to me that someone was able to call a function I wrote that really needed instances with nils instead, so I was forced to check and throw in case they did. It's just not clear and it leads to a lot of unnecessary checking or nil pointer exceptions.
[+] [-] ambrosebs|12 years ago|reply
This rough screencast describes on aspect to the approach http://vimeo.com/55280915
[+] [-] heyadayo|12 years ago|reply
Great language too if you're down with .NET.
[+] [-] leefrank|12 years ago|reply
[deleted]
[+] [-] LindaWell|12 years ago|reply
[deleted]
[+] [-] jafaku|12 years ago|reply
I'm sure there have been great advances. But you are showcasing this as if it was a completely new idea, even though PHP has been using it for a long time. Correct me if I'm wrong.
[+] [-] pbiggar|12 years ago|reply
[+] [-] ambrosebs|12 years ago|reply
[+] [-] TylerE|12 years ago|reply
[+] [-] ufo|12 years ago|reply
[+] [-] emiljbs|12 years ago|reply
[+] [-] memracom|12 years ago|reply
[+] [-] acjohnson55|12 years ago|reply
Unit testing is great for verifying that a piece of code works conforms to specification, but typing verifies that you're using a piece of code as expected. Two different things.
[+] [-] pbiggar|12 years ago|reply
[+] [-] tel|12 years ago|reply
100% enumeration of runtime behaviors is another property, far stronger than any non-dependent static types today, but also exponentially more difficult than 100% test coverage.
Good static types are a cheap way to get probably halfway between those two on a log scale.
[+] [-] steveklabnik|12 years ago|reply
[+] [-] mcguire|12 years ago|reply