Live data from Hacker News

Why we're supporting Typed Clojure

blog.circleci.com

71–77 of 77 posts

Re: Why we're supporting Typed Clojure

#71
post #47

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.

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.

Just kind of.

Most enterprise customers I have worked with, favour dynamic languages just for scripting tasks, while using static typed ones for the large scale projects.

By large scale, I mean, projects with at least three development sites, at least 30 developers, all the different set of skills. With lots of attrition.

The only time I saw it working, was in a project done with TCL, which lacks optional types, but everyone on team was a top developer, the team was small, and located on the same open space. So startup world, not enterprise.

Re: Why we're supporting Typed Clojure

#72

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 callin…

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

Re: Why we're supporting Typed Clojure

#74

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 callin…

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.

Re: Why we're supporting Typed Clojure

#75

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 di…

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 doesn't seem to help much to verify your type correctness before runtime

I don't think that's possible in Python.

> Also, what you'd really want is something that implements type variables

That is possible, you could check what the type of the incoming parameter is and then check that the return value is the same type. I'm not sure that there's an obvious syntax for saying this, but one could always send a string to @typ and have it parse some made-up syntax.

I suspect this would be a lot of effort and it would probably make sens to use a typed language, instead of trying to shoehorn it into Python. I invented @typ so I could quickly document the types in my functions, & with the added advantage that it catches some errors.

> your printargs looks pretty cool! I might just makes something like that for JS...

I look forward to seeing it.

Re: Why we're supporting Typed Clojure

#76
post #72

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 callin…

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 see…

>Pre- and post-checks are of course possible, but I've rarely seen them used in practice.

I agree, I wish more people (especially Javascript developers) saw the value of pre (and post!) checking.

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

This is fair, I just meant to point out that conceptually this isn't new, it's just a new implementation. Can you expand a bit on what you said about duck-typing?

Re: Why we're supporting Typed Clojure

#77
post #72

Earlier quoted context omitted.

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 see…

>Pre- and post-checks are of course possible, but I've rarely seen them used in practice. I agree, I wish more people (especially Javascript developers) saw the value of pre (and post!) checking. >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…

So most type checking, especially in how people write pre- and post-checks, is of the form "is this an X", for example, "is this object an instance of the String class". In duck-typed languages, that's not good enough, because you're not passing an instance of a subclass of a string, you're passing "something that quacks like a string" (aka implements the necessary interfaces to act string-like).

So the type of an object in a duck-typed language is based on the functions and fields it has _now_, not its instance type. Since there is no name for that type, you cannot do "nominal" typing. Instead, you must use "structural" typing, which checks its structure. This is exactly what Typed Clojure does.

An example of how that works in practice, is you say that the 2nd parameter must be a map with one of the following configurations: a key named :foo and a key named :bar, both mapping to strings, or a key named :error, mapping to a string.

Post reply on HN