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

Those changes you mention are actually breaking changes, and Rich Hickey would think so too. (Maybe he wouldn't on the new mode of calculation, but I believe he would for the others.)

The reason: he specifically mentions that tightening the contract should be a breaking change, and adding a parameter is tightening the contract. Same with adding a new field.

I'm only concerned with changes that should not be breaking changes, but are because of implementation issues.

That isn't to say that static type systems are automatically good. If a static type system cannot express dynamic types, it is no good because sometimes, dynamic types are needed.

Speaking of dynamic typing...

Having only dynamic typing means that you have to wait until runtime to catch every mismatch. That's a bad deal when that mismatch may happen in production.

The very existence of TypeScript, the existence of Spec in Clojure, and the fact that type annotations have been added to Python should be enough evidence of this. These were all languages that prided themselves on their dynamicism; if they reneged, there's probably a good reason.

I mentioned above that having static types with no way to have dynamic types is a mistake. I believe it's just as much of a mistake as having only dynamic typing. They are both needed.

But personally, I would make static typing the default.




> and adding a parameter is tightening the contract

If a function took 3 parameters, and I've added another optional 4th one, how is that a tightening? All old callers are still using 3 parameters, their contract has not been broken.

Of course, adding a required 4th parameter is an incompatible change, if you meant that. I wouldn't call it strictly tightening though, since it's incompatible both ways. But yeah, excuse me for being vague, I meant adding optional parameters.

Similarly, adding a field to a struct which the caller does not have to initialize or mention at all, is, in my opinion, also not a breaking change and does not tighten. Since all callers don't need to change their code or semantics.


I thought you meant an extra required parameter.

Adding an optional one should not be a breaking change, and I have an idea or two of how to do it without breaking callers, even in a static language.

Adding a field to a struct should still be a breaking change because that field could be used. If the caller does not initialize it, you might have a bug.

If you're taking about Clojure maps, and not structs, that's completely different. But Clojure maps are open. Structs are closed.

Adding something to a closed thing is a breaking change. Why? Because of what I said above: the new thing needs to exist. Rich Hickey calls this "place-oriented programming," and he hates it for that reason. He's not entirely wrong either because yes, it can easily cause breaking changes.

But when you add something to an open thing like Clojure maps, that should not be a breaking change, and having implemented something like Clojure maps in C, I can tell you that it is not breaking, even in C.




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

Search: