8 ms·
> the better programmers (the ones that know how not to couple shit) favor dynamic typing while those that regardless of experience haven't learned how to keep
by hood_syntax 9y ago
> the better programmers (the ones that know how not to couple shit) favor dynamic typing while those that regardless of experience haven't learned how to keep coupling at bay prefer static types.
Haha, wow. That is some serious reaching there. And let it be known, I'm not referring to myself as some great programmer, because I don't think I am.
1. You imply static typing is a tax rather than something that reduces cognitive overhead as time goes on.
This point is very debatable.
2. You imply that 'clearly, anyone who doesn't favor dynamic programming is a lower quality programmer who doesn't know how to keep coupling at bay'.
That's pretty ridiculous, if you weren't cackling with anticipation at the responses to your flamebait then I have to assume you're serious, and you've already drunk the koolaid.
- wellpast 9y ago1: (add [x y] (+ x y)) (add [^Integer x ^Integer y] (+ x y)) Both of these are equally precise (in terms of telling the computer what to do). The latter one prima facie requires more thinking, more typing, and more work. (Side note: the sky is blue.) 2: I don't mean to make such the broad generalization that you're jumping to here. What I mean to say is that static typing in the traditional mode (non-a la carte, applied everywhere, w/ all of the typical idioms of ADTs, pattern matching, etc etc) may help in cases where your code is heavily coupled, complex etc, but I think that its a needless impedance in higher-quality codebases.
- Drup 9y agolet plus x y = x + y This is a statically typed function. If you are going to talk about static typing, learn about type inference and avoid making yourself ridiculous. Also, the fact that types are dynamic doesn't mean you don't have to think about them, you still have either type errors (like in most lisps) or implicit coercions (like in JS, you probably don't want that).
- wellpast 9y agoYou're missing my point. In your example, somewhere you have to express your types. So just move my example over to that point in your code.
- Drup 9y agoSure. Just like somewhere, you have to define the semantics of + on the various primitive in your lisp-based system. Oh, surprise, you do that with a typecase/runtime type check. There are genuine arguments between static and dynamic typing. The assumed annoyance of writing type signatures is only a valid point for specific type systems such as Java, and is certainly not a generic concern. As usual: https://ro-che.info/ccc/17 https://ro-che.info/ccc/17
- wellpast 9y agoIt's not just about "writing type signatures". It's about expressing the semantics of your solution to some business problem. When my product manager comes to me and says "I want a button here that when you press it, it add the user-entered value in input box 1 to the value in input box 2." Okay, done: (button :on-click #(+ (box1-value box2-value))) All I had to know was that the function contract/semantics of "+" is that it adds two numbers. Now I am done. Let's say that night I wake up sweating realizing that the user could type in the String "one" and "two". Thankfully this before my push to production, so I go re-implement "+" to support English numbers. Okay, now I go live. Well, now my user types in roman number "I". And a weird value is produced. My product manager doesn't care about this class of users, so great I do nothing. The point of this is that every step of the way, my choice to type check or not is a la carte. Not forced down my throat. Types are my tool, not my religion.
- deleted 9y ago[deleted]
- tome 9y agoYou re-implement the primitive operation "+" to support adding strings that name English numbers? Is that actually possible in Clojure, or did you mean something else?
- wellpast 9y agoAnother way to think about this. When you and I are defining "plus" in this way, you may be thinking types (and how they are inferred and everything). I am simply saying I want "plus" semantics to be identical to "+"... If "+" is capable enough to add the String "one" and "two" together, I'll take it. If one of my users types in a roman numeral "I" and "+" yields wrong behavior (throws, or produces bad value), then I have to think about types. But maybe that never happens... (I'm not saying this is how to code, but I'm clarifying that you don't have to think about types to get the semantics/precision. You just want to think about types, can't help thinking about types, or something else, you tell me.)
- tome 9y ago> When you and I are defining "plus" in this way, you may be thinking types Nope. No thinking in types required there. > I am simply saying I want "plus" semantics to be identical to "+". Yup. And that's exactly what the code that Drup pasted does. > If "+" is capable enough to add the String "one" and "two" together Yup. And that's exactly what the code that Drup pasted will do.
- wellpast 9y agoI was simply responding to Drup's "the fact that types are dynamic doesn't mean you don't have to think about them"... If you're telling me you don't have to think about types, then you and I are on the same page. But it sounds like we're talking Haskell here, so afaik, somewhere Haskell is going to ask you to specify types so that it can complete its type-proof (i.e., compile.) If you're saying No, Haskell doesn't need that, then I'm afraid you have a dynamic language on your hands.
- wellpast 9y agoAnd more: Suppose your types are Strings. And your plus operator can add "one" and "two", but fails adding roman numeral "I" and "II", my guess is you'll another type/ADT into your static typing called RomanNumeral so that your type proofer will check you at compile. Meanwhile I will do exactly nothing because my product manager says he doesn't care if the user types in roman numerals. Which means I will be building my next business feature while you're still doing type math.
- tome 9y ago> my guess is you'll another type/ADT into your static typing called RomanNumeral so that your type proofer will check you at compile. Hmm, no. Why would you guess that? That makes no sense at all.
- wellpast 9y agoWell then what is your criteria for having a String that can represent both English spellings of numbers and a String that represents roman numerals. If you say "I choose just String. I.e., I overload String to contain both types of values. Then you are doing dynamic typing. So why in that case do you choose dynamic verification, but in other cases not? What is your criteria for when you choose static types versus dynamic types? Or do you just go by instinct?
- dang 9y ago> avoid making yourself ridiculous This breaks the HN guidelines. If you're going to comment on a flamewar topic, you need to do better than this, even when someone else posted flamebait. Especially then. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html
- Crespyl 9y agoAre the two really equally precise though? There are many languages in which the `+` operator can be applied to types that are not integers.
- wellpast 9y agoIt depends on what you're trying to express to the computer. Are you trying to say plus two integers -- if you are trying to say something specific about the types -- then you have to say types to be precise. But if all you're doing is saying I want "add" to have the same semantics as "+", regardless of types, then you are perfectly precise and you are done. This is a toy example, obviously, but this line of reasoning extends to real-world examples.
- bitwalker 9y ago1: In a static type system with inference, both examples would just be (add [x y] (+ x y)) as the `+` operator is enough to infer that the parameters need to be a number. So your point is true for some statically typed languages, but certainly not all (ML-likes, Haskell-likes, and others with strong type inference). 2: In my experience, ADTs (and pattern matching in particular) make coding problems much easier to solve (and the code itself considerably simpler) than the alternatives in many languages. For example, I'm writing a compiler in Go, for fun, and a lot of tasks would be far easier and more concise to express with ADTs/pattern matching. Another example is working with pattern matching in Elixir/Erlang, especially with binary data, which is beyond easy to express a parser for with pattern matching. Elixir and Erlang are dynamically typed, and have gradual typing via Dialyzer (though it's rather different from clojure.spec I believe), but pattern matching is pattern matching, and it's indispensable in my opinion. Using something dynamic, like Lisp/Javascript/Ruby/Etc. would make it much more difficult to navigate the code for something like a non-trivial compiler (in my experience), and more difficult to reason about how it will execute. The other thing I don't see mentioned very often is that if the compiler can't reason well about your code, then it can't optimize it very well. Even with a JIT, you are paying a performance cost that is non-trivial, unless you happen to be using a language with a particularly good JIT, performing tasks that the JIT is good at optimizing at runtime. For a lot of tasks, this overhead doesn't matter, but I would rather lose some flexibility to be able to use the same language for a broader array of tasks. Recently I was taking a stab at translating some code for an Earley parser from some dynamic languages (Javascript and Python) to Go, again for fun, and in both cases found it was impossible to do so because of the way the dynamic features of the language were abused - basically I would have to throw out everything and write it from scratch. The code was hard to reason about, because while reading it, you think you are working with values of a certain type in one function, but the same value somewhere else is getting treated like a different type. You basically have to execute the code to see what it does. Such flexibility can make for more concise code, but when the code _isn't_ concise, it can make it incredibly difficult to untangle. That's just my experience though. I'm an Elixir/Erlang programmer during the day, so I'm not anti dynamic languages by any means, but I have definitely found it easier to build certain types of applications in statically typed languages.
- 9y ago