6 ms·
"a statically typed language can do the same things a dynamic language can do, but not the other way around" It's interesting you'd say that, as I'd consider t
by weavejester 9y ago
"a statically typed language can do the same things a dynamic language can do, but not the other way around"
It's interesting you'd say that, as I'd consider the opposite to be true. There are functions that are trivial to write in a dynamically typed language, but are hard to statically type. For instance, the `assoc-in` function in Clojure.
"Another thing static types do for you is that they make things in your application more discoverable. Instead of tracing through to figure out which data is available and operations something supports, the compiler tells you."
You don't necessarily need static typing to give functions some form of type signature or specification.
- flavio81 9y agoI also find the opposite to be true, as you do. The human mind and human problems, operate more like a dynamic language. To put it in a simple, silly example: When i tell you to "cut something with a scissor", the scissor doesn't specifically cut paper; there are many things that can get cut by a scissor. Or when you take a pot, put it over the stove and boil water, you do it and the pot is not specifically designed to boil water, the pot can heat anything; so you can say that many operations (verbs) in real life do not get performed in a "static typing" way, but in a "dynamic typing" or at least "duck typing" way.
- bbatha 9y agoBoth of those examples are trivially modeled with typeclasses (java style interfaces will also cut the mustard here too). Your paper example I would have a “Cutter” and “Cuttable” type classes to describe things that cut and can be cut. In languages like Haskell this only involves a couple extra lines of ceremony over writing a “cut” method on each type. The pot example is even cleaner with types and show the power of them. I’d have a Pot typeclass that can heat things. I’d have a liquid class for all liquids that water implements and finally a boil free function that takes a pot and a liquid. Exactly as expressive but now with compile time checking.
- dragandj 9y agoAll this is covered in Rich's talk. Your Cutter and Cuttable are different from my Knife and Cuttablito. When your program needs to talk to outside world, it all becomes messy.
- gmfawcett 9y agoWell it's strictly true, in the trivial sense; although the ergonomics might be unpleasant. Many static languages provide a Dynamic type, into which you can stuff any value. The type supports a mechanism for querying the inner type of the Dynamic value, and extracting it. So yes, you can implement dynamically-typed data structures and logic in a statically-typed language. But to use this approach in a widespread way, it might take a lot of scaffolding to make the experience pleasant. As Greenspun warned us, you might just end up implementing a crappy Lisp. :) https://en.wikipedia.org/wiki/Greenspun's_tenth_rule https://en.wikipedia.org/wiki/Greenspun's_tenth_rule
- mightybyte 9y ago> There are functions that are trivial to write in a dynamically typed language, but are hard to statically type. For instance, the `assoc-in` function in Clojure. This is not a hard function to write in Haskell. You make it operate on a list of maps, which is what the Clojure one is doing too. > You don't necessarily need static typing to give functions some form of type signature or specification. But you do have to have static typing to make sure those signatures are automatically verified to be coherent. It seems like you're thinking about my statement from a turing-complete computable point of view. But I meant it from the point of view of what the compiler can do for you. It's not what things you can compute, but what things will be automatically checked.
- weavejester 9y ago"This is not a hard function to write in Haskell. You make it operate on a list of maps, which is what the Clojure one is doing too." It's harder than you think. Just try it. I believe it's possible to achieve in Haskell, but it requires some rather esoteric type system extensions. "But you do have to have static typing to make sure those signatures are automatically verified to be coherent." If you want a guarantee, then yes, but you can get an good approximation of correctness with runtime specs coupled with test generation.
- mightybyte 9y ago> it requires some rather esoteric type system extensions No, it's just a simple [Map Text Text]. Or if you want a little more safety, then [Map Text Value]. > you can get an good approximation of correctness with runtime specs coupled with test generation. But this requires more code. More code is error-prone and takes time to write and maintain.
- weavejester 9y ago"No, it's just a simple [Map Text Text]. Or if you want a little more safety, then [Map Text Value]." I think you're confusing `assoc-in` with `assoc`. The latter is trivial to type; the former is not. The problem with typing `assoc-in`, is that the type of the vector of keys is derived from the type of the nested map in a way that's hard to generalize. For example: (assoc-in m [a] b) Has (approximately) the type signature: Map a b -> a -> b -> Map a b But: (assoc-in m [a b] c) Has the type signature: Map a (Map b c) -> (a, b) -> c -> Map a (Map b c) And so forth. "But this requires more code. More code is error-prone and takes time to write and maintain." No it doesn't; you can generate and run the tests from the function's spec automatically. If I run `(clojure.spec.test.alpha/check)` in Clojure, it will generate and run tests for all functions that have specs.
- spion 9y agoHere is assocIn variant 1 type in TypeScript: declare function assocIn<T, K extends keyof T>(t: T[], x: [number, K], val: T[K]):T[] You can try it out: https://goo.gl/3JrmX3 https://goo.gl/3JrmX3
- weavejester 9y agoIt generates a type error when I write: assocIn({ a: 1, b: 2 }, ['b'], 4)