12 ms·
The social pressure to love static typing notwithstanding (think less of me if you will), the reason I got turned off by it eventually are the ivory towers that
by nurple 3y ago
The social pressure to love static typing notwithstanding (think less of me if you will), the reason I got turned off by it eventually are the ivory towers that invariably get built up around them. I've spent a decade each building software in both paradigms and I now prefer not to use type systems.
I find dynamic typing similar to how unit testing is a forcing function for writing composable code, it acts as a forcing function to writing simple code; simple to read and simple to comprehend.
The argument that it helps inexperienced developers approach the codebase is, IMO, a poor one as it tends to incentivize an iteration loop that lacks understanding and is simply trying to make all the red go away. In fact I find that the type system is often a barrier to truly understanding what's going on as it effectively adds a very domain specific language to every project that has to be learned on top of the language itself.
There are methods to solving the problems presented in TFA that are just as robust as using types and which are simple to understand. Can types be used in a simple way? Sure. Are they ever? Not in my experience. I also don't like autocomplete, so take that as you will.
I may just be a grizzled greybeard screaming "the code _is_ the documentation", but perhaps that is born from my deep dissatisfaction with the current breed of get-big-paycheck-chatgpt-said-it's-right devs that are currently flooding the industry.
- deleted 3y ago[deleted]
- busterarm 3y agoI was going to write a response pretty much exactly like yours. Also, the domain we're in is engineering. There are no single correct decisions and everything is about trade-offs. And that's good because otherwise our jobs would be the first to be automated out of existence. All of the discussion in this thread about people "thinking less of" other engineers for their opinions/experiences is fucking gross.
- purplerabbit 3y agoYour bio says “most people are stupid” — how’d you arrive at that conclusion without judging people?
- busterarm 3y agoThere's a chasm of difference between blatantly self-destructive life choices and forgetting that your profession is about making decisions based on multiple options. Also you only half-quoted me. It's "... and/or on drugs". Also people being stupid doesn't mean that I don't consider anything they say. Even a broken clock is right twice a day.
- enraged_camel 3y ago>> Also, the domain we're in is engineering. There are no single correct decisions and everything is about trade-offs. Yep. In my experience, hardliners tend to not be great engineers, even if they have decades of experience.
- JohnBooty 3y agohardliners tend to not be great engineers 100% agree. "Strong opinions, weakly held" is okay with me though. I don't call that "hardlining." Although, sometimes it's hard to differentiate "strong opinions, weakly held" from "strong opinions, strongly held, not open to new ideas."
- tasn 3y agoI think you make a good point about the ivory towers and the social pressure being a turnoff for adopting certain technologies. Though I also think this doesn't detract from their potential technical merits. As in, a technology can be both great, and have everyone about it be pretentious. > I find dynamic typing similar to how unit testing is a forcing function for writing composable code, it acts as a forcing function to writing simple code; simple to read and simple to comprehend. I don't agree with this argument, I think it's akin to saying "I like driving blindfold because it makes me drive slower". You can use linters with limits on line length and number of params if this is a goal for you, no need to go indirect with the restrictions. I agree that typing is not the only solution, I'm just saying that I think the ROI is massive in types, so I think this should be the first tool people go to. Almost no investment, and a lot of benefit. I agree with "code is the documentation", I even made a point about documentation in the post, but I argue that typing is part of the code. So "the code is the documentation, and typing is part of the code" is how I'd phrase it.
- sodapopcan 3y ago> > I find dynamic typing similar to how unit testing is a forcing function for writing composable code, it acts as a forcing function to writing simple code; simple to read and simple to comprehend. > I don't agree with this argument, I think it's akin to saying "I like driving blindfold because it makes me drive slower". You can use linters with limits on line length and number of params if this is a goal for you, no need to go indirect with the restrictions. I was assuming this is more along the lines of writing clear variables names and writing functions that make it obvious what the return value is.
- koonsolo 3y ago> I also don't like autocomplete You must have a crazy good memory. I switch between multiple languages, and autocomplete lets me easily see what variant of a function this library uses again. You know everything by heart?
- imran-iq 3y agoI also don't like autocomplete. The reason being that not having it actually forces me to learn the libraries I am using. > You know everything by heart? You eventually reach that point. Do you still look down to see which keys you are typing? This is also has the nice side effect of pushing you to use libraries that are stable and have good documentation as you can always reference them if need be.
- lsaferite 3y agoMy working memory has limits. I consume and use a lot of information on an ongoing basis. The contextual shift from codebase to codebase is already large, add in a language change and I would venture to say that most people need a little assistance to make sure they remember syntax and specific method calls.
- koonsolo 3y agoMy memory is a leaking bucket. My typing however, is very fast. Take for example the substring function. I wouldn't know which one it is for JavaScript, Haxe, ActionScript3, C#, Java, Python, C, C++, PHP. I know I used it at one point for all of them. For languages like JavaScript, Java and C#, it's probably a method, so you can start typing. Might be substring(), might also be substr() or something like that. For Haxe, I thought it was not a method so I think it's either part of Std or StringTools. If I use autocomplete, I have it in a few seconds, and I can also see the documentation on the parameters. Is the second parameter an index or a length? To be honest I have no idea. And the good part is, thanks to autocomplete I don't need to know. Also, if you work in a big codebase, you can't know every class. Needing to dig through code seems such a waste of time.
- 3y ago
- digging 3y ago> The argument that it helps inexperienced developers approach the codebase is, IMO, a poor one as it tends to incentivize an iteration loop that lacks understanding and is simply trying to make all the red go away. In fact I find that the type system is often a barrier to truly understanding what's going on as it effectively adds a very domain specific language to every project that has to be learned on top of the language itself. This is very interesting and at first blush strikes me as backward. I wish I could sit in your office and see this happening, because I find it hard to imagine and I would love to know what that looks like. (And I have way less experience than you so I'm not saying it can't happen.) Specifically, I find the domain-specific logic in my field is impossible to grok in dynamically typed codebases, while statically typed ones actually teach the developer what the business logic is. > I may just be a grizzled greybeard screaming "the code _is_ the documentation" Also confusing to me! In all my experience, static typing is what allows the code to be the documentation. Without it, there's no way to know what properties this object has or why we have a check for this certain property that I thought didn't even exist on this object. (Other than comments - maybe I'm on a weird team but I don't know anyone other than me who leaves comments of any significance.)
- spankalee 3y agoComments are great, but they should usually explain why, not what. Good, long variable and function names, along with breaking complex expressions into multiple statements with those nice variables names can help the code itself describe the what of the process. And then static types help describe the what of the types of data even more. That lets you save the comments for more useful things than an ad-hoc type system, like "// We need to do this because..."
- hparadiz 3y agoCode coverage reports with complexity score for every function is the best teacher for this. I particularly love how Scrutinizer CI does this.
- graypegg 3y agoThe social pressure side, I totally get. People get very defensive about this sort of thing, and act somehow personally offended if anyone does the opposite. I say that as someone that quite likes static types. I don’t care, do what you do!
- xedrac 3y agoI had this attitude too until I got sucked into a very large Python project. I now refuse to use Python for anything bigger than a few pages of code. It's so poorly suited to correctness that it takes an enormous amount of test coverage to gain any confidence. And don't get me started on refactoring. After this experience, I suddenly care a lot more what other people use, because it may impact me in the future. Please don't use such languages for big complex "must be correct" problems.
- the_af 3y ago> I now refuse to use Python for anything bigger than a few pages of code. Your comment pretty much echoes my opinion. Unfortunately in the problem space I work (data) Python is pervasive, but fortunately, it can be used in small isolated snippets, or Pyspark where this doesn't matter much. For general large projects... I feel your pain.
- tipiirai 3y agoI think the social pressure relates to people forcing _you_ to use a language that you wouldn't personally go with. Pretty sure the pressure is highest with TypeScript currently.
- spankalee 3y agoI really don't understand these lines of argument, because they seem to me to be almost entirely backwards. > I find dynamic typing ... acts as a forcing function to writing simple code; simple to read and simple to comprehend. I find the opposite true. Many super-dynamic patterns are hard to type correctly. Good type systems tend to encourage simpler patters so you get simpler types. > The argument that it helps inexperienced developers approach the codebase is, IMO, a poor one as it tends to incentivize an iteration loop that lacks understanding and is simply trying to make all the red go away. Making the red go away is important because the red indicates a problem! This is a lot easier than other ways of discovering the error. Why would you want to discover the error later? > I also don't like autocomplete, so take that as you will. This is why I'm with commenters who say they don't trust people who are against static typing... I'm extremely suspect of computer programmers who don't want computers to help them program.
- zsyllepsis 3y ago> Making the red go away is important because the red indicates a problem! This is a lot easier than other ways of discovering the error. Why would you want to discover the error later? I don't think that's what the parent to your comment is arguing. They are arguing that "making the red go away" isn't the goal, rather that correctness is, and that it's easy to conflate the too when you focus too much on the "red" part, and don't pay attention to the "correct" part. Worded another way, the mantra of "if it compiles it works" can lead to a dangerous false sense of security if you don't understand the limitations of your type system and what parts of your program is may or may not cover completely.
- spankalee 3y ago> the mantra of "if it compiles it works" Very few people have this mantra, much less without qualification. That's more of a ML or Haskell kind of point of view, and even then it's known to not be a guarantee. A type Int -> Int -> Int isn't going to enforce that you implement multiplication correctly, instead of add or just 0. "I refactored, fixed type errors, and it just worked!" is a thing I see a lot, but from people who just experienced it, because it happens a lot. It's a good thing.
- ransom1538 3y agoWhen I hit ctrl+save, the code should be instantly ready to test, less than 200ms. Waiting for 30 seconds to see code is an ETERNITY to people that code fast, 1k lines per day. I have been on teams that wait 5m to test code, what a waste. Fast feedback loops in code are critical, just like design, or anything important. Types seem like some weird religion, the people that use them cannot be talked out of it.
- splintercell 3y agoI highly recommend you to check out ReScript. Amazingly fast compile times. Watching typescript teams spent 30 seconds on the recompile is insane for me. in fact, the whole ocaml family of programming languages are mega fast. The most important feature of a very fast compile time is that you can load it with types after types and write in your whole mental model, without worrying about your build process slowing down.
- jcparkyn 3y ago30+ second compile times is definitely not something inherent to statically typed languages. 200ms is rare, but plenty of static languages manage <5s for large projects and much less for small ones. Not to mention that a good IDE will incrementally check types in well under a second as you type, so the need for frequent test runs is lower. That said, I agree 100% about the importance of fast feedback loops.
- paulmd 3y agoin my experience dynamically typed languages are slower to compile than dynamic ones. groovy, for example, is massively slower to compile than java (it is something like a factor of 10x in our codebase), and the whole point is literally to give you python-style code velocity. that's not to say that you can't write slow statically-typed compilers. but the strict syntax tree gives you much faster parsing/etc. dynamic languages can't avoid this either, it just does it at runtime instead. and hot-reload for function changes/etc is very possible in a similar fashion to dynamic compilers too. And if you add a space or a bracket, because of the parsing problem, you can't even notionally contain that to a single part of the AST, the whole thing has to be re-parsed. again, not that you can't make a static language compile very slowly, or that any given implementation is necessarily faster. but dynamic languages almost strictly have to do more parsing work, and have to do it more often, over larger parts of the codebase. and that's expected - static languages offload some of this "preprocessing" to the developer!
- eyelidlessness 3y ago> I find dynamic typing similar to how unit testing is a forcing function for writing composable code, it acts as a forcing function to writing simple code; simple to read and simple to comprehend. If this were broadly true for most developers using dynamically typed languages, it would be a very compelling argument indeed. But I think there’s pretty strong evidence the opposite is generally true: actual types produced to document real world dynamic code tend to be vastly more complex than the equivalent functionality implemented with static types from the outset. In the TypeScript ecosystem, DefinitelyTyped is an excellent source of countless case studies. The types they provide are typically definitely not, as you put it, “used in a simple way”. That’s not complexity inherent to the type system, or the type definitions as provided; it’s complexity inherent to the dynamic code they describe. Equivalent packages which were statically typed from the outset tend to have much simpler interfaces because the types are defined upfront rather than retconned onto existing APIs. That doesn’t necessarily mean their interfaces are absolutely simple, but they’re typically relatively simple by comparison. I’d go so far as to say that you can’t know how simple or complex an interface is without specifying it. If “the code is the documentation” (which I agree is a great ideal!), then interfaces without code specifying them are under-documented by definition. The further the code specifying the interface is from the interface itself, the more obscured your documentation is.
- hparadiz 3y agoDynamically typed language have very clear rules. It's not magic. If you know these rules nothing about dynamically typed code is inherently problematic. It's the difference between logic being in the code versus in the run time. You accept hundreds of rule sets built into the run time all the time.
- MrJohz 3y agoAll programming languages - all computers even - have very clear rules. The complexity in software development usually has less to do with getting a computer to understand its own rules, and more to do with the boundaries between humans and those rules: for example, encoding human ideas into rigid computer rules, or trying as a human to understand the computer rules that someone else has written. So when you say "if you know these rules nothing about dynamically typed code is inherently problematic", my intuition says "I probably don't know these rules". That goes for some of the basic rules like "the first argument to this function is the haystack, the second is the needle", but it also goes from some of the more complex rules like "functions that take a user ID can also take a user object and extract the ID from that" or "the allowed states for this FSM are X, Y, and Z, and are always written in capital letters". More importantly, a lot of the rules for my difference will not have been written by me, they'll have been written by my colleagues, or else they were written by me, but it was more than six months ago and my memory is a bit hazy on the details. The point the previous poster was making, I think, was that while the rules may be very explicit (this is, after all, what any programming language is: explicit rules for a computer to follow), they can also be very complex. And, more specifically, the DefinitelyTyped examples show that the rules for dynamic software often tend to be very complex, or at least, complex enough to present difficulties when being modelled by a type system explicitly designed to model dynamic code.
- danenania 3y agoI'm fully a convert to static typing and don't think I'll ever willingly do another project without it, but you make a really good point about how people tend to always go overboard with types. I did this early on in a large TypeScript codebase while learning TypeScript, and now I regret it. I'm still far better off than I'd be without static types though. This also happens with tests. It's easy to get wrapped in testing libraries and abstractions and spend way more time than you need to. The 80/20 rule applies in both areas. You get 80% of the benefit with 20% of the abstraction. It's usually a mistake to try to go beyond this. Of any popular language I'm familiar with, I'd say Go is the one that follows the 80/20 rule best. It encourages you to focus on solving the problem rather than leading you down rabbit holes of various kinds, including with types. That's not to say Go doesn't have its issues, but it really is excellent at discouraging over-engineering.
- thegeekpirate 3y agoHeh, before reaching your last paragraph, I was going to recommend Go as the remedy to your woes. Glad you've discovered it yourself!
- Djeman 3y agoCode can not be documentation by meer definition. Code is written in programming language and documentation in spoken language. So documentation has important function of explaining intention of code in non trivial sections. Of course you wont give explanation of CRUD actions or other patterns you are using but business rules get coded and people reading that code need to know where rules come from and what are expectations either directly in code or by reference. Otherwise you revert to finding origin of code in source control and related task if you are lucky to have that level of tracking.
- mecha_ghidorah 3y ago> The argument that it helps inexperienced developers approach the codebase is, IMO, a poor one as it tends to incentivize an iteration loop that lacks understanding and is simply trying to make all the red go away. In fact I find that the type system is often a barrier to truly understanding what's going on as it effectively adds a very domain specific language to every project that has to be learned on top of the language itself. What? It helps developers inexperienced with a given codebase (not necessarily inexperienced generally), because you can very easily understand the types being passed into functions. You may need to understand why a function is behaving a certain way, so you look at the arguments, if you see a type you don't recognize you can push a button and your IDE will take you to the definition of that type. If you want to you can with another key combination see all the inheritors of that type, and so on. It makes it much easier to feel confident about what one can and can't do with any given object at any given time, which is helpful when one is getting up to speed with an existing breed of architecture.
- DanielHB 3y agoDynamic types do make people create more dynamic APIs because it is a lot easier to let the parameter be number or string or format-function or bigint, etc Dynamic APIs are super hard to reason about if you don't have types to ensure you are calling your APIs correctly (function argument A can be number or string, but not formatFunction) So having static types makes your APIs less dynamic because people are too lazy to type them correctly. Which in general is good in my opinion, making an API dynamic should be done only when it is really helpful to do so. The other point is null-guards which _some_ (but not all) type systems enforce, null-guards are just 100% good thing.