8 ms·
The core of the argument is that the features of static code bases are something you need anyway when programming in the large, and I basically agree with that.
by trjordan 13y ago
The core of the argument is that the features of static code bases are something you need anyway when programming in the large, and I basically agree with that.
I'm not totally convinced, though. Take the simple case of "tell me what range of values to expect here". Java / C++ deal with this with their types, and you can be reasonably confident that you're getting the object you expect. As I'm sure somebody will mention, those types are a bit weak, and can't guarantee the object you get is exactly what you expect. What if you don't test with the right sub-class? What if it's an int, but it's out of the range you expect?
"No, that's not what types guarantee!" you may say. And it's true.
I think one of the problems is that language features aren't perfect. Forcing everybody to admit they're dealing with integers is more desirable than no contract at all, but would it be better if you dealt with Scores, which where integers in the range of 0-100?
In a big enough codebase, the language is never powerful enough to handle all your checking for you, so you need some level of discipline. I worry that by having something "good enough" when your code base is moderate, it allows teams to slip by into "large" without ever considering what their tools, conventions, and limitations should be.
- gaius 13y agoBetter than that, you can enforce that a Score is a Score, not just any integer between 0 and 100. You can put units in there, so a Score must be in Points. This is all normal in Ada and off the top of my head, F# has it too.
- platz 13y agoJust create a type in any language and you can do it there too
- gaius 13y agoWell, yes and no. You could in Java create a class called Score with get() and set() methods, set() taking another class called a Point as its input, and throw an exception if the value of Point is outside the range, but the overhead of that would be huge both at development and at runtime. With expressive types in the language, there's minimal extra effort in development (in many cases much less since now the compiler can do things that otherwise you'd need unit tests for) and none at all at runtime.
- jarrett 13y agoYep! Another huge benefit of static typing, particularly for systems that deal with lots of numbers that mean different things. (Some are lengths, some are durations, some are speeds, etc.) Don't want your airplane to crash because you passed in square feet instead of meters per second? Have the type system check your units.
- awj 13y ago> Don't want your airplane to crash because you passed in square feet instead of meters per second? Airplane? Hah, think bigger: http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_f...
- ygra 13y agoIn an application at work where we deal with mapping and geo-coordinate systems and stuff we frequently all sorts of fun little bugs because a point on the map doesn't know whether it's in geographic coordinates or in the current transformation system or in screen coordinates. They all use the same class and can be freely mixed. Alas, my suggestion of using different types to encode different coordinate systems was more or less ignored (too much effort cleaning up a 15 years old codebase).
- humanrebar 13y agoI largely agree with this, but also consider the following: 1. I have a function 'saveScore' that has a parameter 'score' that is an int. 2. Users of my function frequently misuse my function, passing in negative scores, so my team decides a range-checked Score parameter makes more sense. 3a. In a static language, users of my new code get compilation errors saying 'saveScore' takes a 'Score', not an int. 3b. In a dynamic language, at best, devs that use my code get an easy-to-read exception thrown at runtime. This assumes I'm thorough enough to check my preconditions and throw an understandable error message. This also assumes all code paths are covered before the code is released to customers. In short, static languages provide facilities for library and framework authors to enforce a little discipline in the consumers of their code.
- spion 13y agoNow what if you have a function that returns an int, which you want to use as the input argument to saveScore? You'd probably use a conversion function that returns a Maybe Score...
- runT1ME 13y ago>What if you don't test with the right sub-class? What if it's an int, but it's out of the range you expect? Type systems can do all this and more. https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0 https://github.com/milessabin/shapeless/wiki/Feature-overvie... They can assure you handle all possible control flow cases with ADTs and pattern matching, they can facilitate automated testing, etc. Just because it's not how java/c# do it, doesn't mean it's a limitation of 'typing'.
- ubernostrum 13y agoThe problem is that your argument is basically boiling down to "this hyper-experimental language that only three people on earth use can do it, therefore you should use Java/C++/C#".
- saryant 13y agoShapeless is a Scala library, not a language.
- asdasf 13y agoHow very dishonest of you. It actually boils down to "a bunch of common languages do it right, so use one of those instead of java".
- ubernostrum 13y agoWell, no, the dishonesty is basically in arguing that statically-typed languages have all sorts of wonderful features... while omitting that the set of statically-typed languages which have those features, and the set of statically-typed languages people actually use, do not overlap much.
- runT1ME 13y agoLinkedIn, Twitter, FourSquare, Netflix, Rackspace, Firebase, Hulu and a ton of others use Scala. How is that dishonest?
- wcummings 13y agoAny decent programmer working in a dynamically typed language will implement pre-checks (and maybe even post-checks) to validate types at run-time. Some dynamic languages even allow for type specifications and static analysis, optionally or through an external tool.
- kasey_junk 13y agoI am strongly anti-dynamically typed for this reason. I spent 5 years in a dynamic language writing so many asserts/unit tests to handle basic compiler type cases that it more than invalidated any argument for conciseness or time to market.
- andybak 13y agoDid you consider not doing that, then? Plenty of code-bases don't and the sky doesn't fall in.
- emn13 13y agoThat just doesn't happen. People don't check pre-conditions and, frankly, they're right not too: checking all the ways your input might be wrong is often very wordy (much more so than static types), and usually slow. Not to mention that it's not at all trivial to check preconditions; if your program has any kind of duck-typing or dynamic dispatch it's often very hard to check more than the immediately obvious (can it quack?), and that check is often furthermore redundant because you'll use the function. Worst of all, this is extra code that itself can have bugs (and it's code that's likely to see almost no usage in production since you don't make a habit of passing invalid input). Of course, you could check that extra code with extra unit tests... If you want to check preconditions rigorously and pervasively, use a statically typed language (and be a little realistic in what you can check). If you want short code without ceremony, use a dynamic language and don't uglify it with more boilerplate than the worst statically typed language. I've seen that kind of code in ruby, and it's really not a joy. Real life in a dynamic language: people introduce some checks in some high-risk functions, and call it a day. And that's... Just Fine.
- 13y ago
- mmatants 13y ago> ... would it be better if you dealt with Scores, which where integers in the range of 0-100? That's what value objects are all about, and yes - you can do that in a mainstream language such as Java/C#. http://en.wikipedia.org/wiki/Value_object http://en.wikipedia.org/wiki/Value_object I strongly recommend that pattern.
- jiggy2011 13y agoWell you could subclass the Integer class and take that as a param (except you can't in Java because Integer is final, so you would need a wrapper class) then throw an exception in the constructor.