top | item 6459769

Why we're supporting Typed Clojure

212 points| pbiggar | 12 years ago |blog.circleci.com

73 comments

order
[+] breckinloggins|12 years ago|reply
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.

[+] pbiggar|12 years ago|reply
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.
[+] ambrosebs|12 years ago|reply
What is intellisense on a hash?
[+] anaphor|12 years ago|reply
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.
[+] ambrosebs|12 years ago|reply
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.
[+] juandopazo|12 years ago|reply
Typed Racket and Typed Clojure are major sources of inspiration/reference for typed versions of JavaScript like TypeScript and possibly future versions of EcmaScript.
[+] zcrar70|12 years ago|reply
Typescript also uses 'gradual' typing. See http://siek.blogspot.co.uk/2012/10/is-typescript-gradually-t... - Siek is referenced in the original post, too.

Clojure's type system sounds more powerful than Typescript's though.

[+] ambrosebs|12 years ago|reply
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.

[+] pjmlp|12 years ago|reply
This is great news for Clojure.

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
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.

[+] cabalamat|12 years ago|reply
People interested in optional types for Python may be interested in my @typ decorator that implements them: https://github.com/cabalamat/ulib/blob/master/debugdec.md

Sample:

    @typ((int,float), ret=(int,float))
    def square(x):
        return x*x
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
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...

[+] wcummings|12 years ago|reply
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.

[+] pbiggar|12 years ago|reply
OP here. I do actually believe what I said.

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
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.
[+] draegtun|12 years ago|reply
Perl6 & Rebol are some other examples of dynamic languages which come with optional typing.

NB. And I believe Perl6 in certain cases will/can raise compile-time type errors.

[+] dep_b|12 years ago|reply
There one thing that really stirred my interest:

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
nil is explicit in Typed Clojure, and it's a goal to statically avoid misuses of nil.

This rough screencast describes on aspect to the approach http://vimeo.com/55280915

[+] heyadayo|12 years ago|reply
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/

Great language too if you're down with .NET.

[+] jafaku|12 years ago|reply
> 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.

[+] pbiggar|12 years ago|reply
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.
[+] ambrosebs|12 years ago|reply
You're correct. Sam Tobin-Hochstadt is the star of the show, and is given a mention in the article, along with his fantastic Typed Racket.
[+] TylerE|12 years ago|reply
You're totally wrong. For one thing, PHP coerces WAY too much for any type system to be effective. That's just plain duck typing.
[+] ufo|12 years ago|reply
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.
[+] emiljbs|12 years ago|reply
On this note, this doesn't seem to be more powerful than CL:s optional typing, am I wrong?
[+] memracom|12 years ago|reply
There is already typing in Clojure (and Python and Ruby). It`s called "100% unit test coverage". If you want it, you can have it now.
[+] acjohnson55|12 years ago|reply
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.

[+] pbiggar|12 years ago|reply
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.
[+] tel|12 years ago|reply
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.

[+] steveklabnik|12 years ago|reply
I write lots of Ruby, and I downvoted you because this isn't very constructive.
[+] mcguire|12 years ago|reply
100% of what? The parameter value space?