4 ms·
I recommend Dijkstra's paper: "On the foolishness of "natural language programming" [1]. It explains how natural language is a very poor way to express program
by Peaker 12y ago
I recommend Dijkstra's paper: "On the foolishness of "natural language programming" [1].
It explains how natural language is a very poor way to express programs, and how it held back science and progress for many centuries.
Strong types describe your code precisely. If your code doesn't match the model yet, that's fine.
But your code has invariants in it. Things like: "this variable can never be nil, that variable can". These invariants can relatively easily be encoded as static types. Not doing so is just throwing away safety and documentation for virtually no benefit.
Other invariants are similar. Instead of documenting them or keeping them in your head, you let your compiler worry about them. And then when you break those invariants, the compiler is your friend! He helps you go and find all the other pieces of code that relied on the broken invariant, so you can fix them.
You say you prefer a more flexible language: But Go is extremely inflexible. It has a very primitive set of tools to do everything, clumsily. A language like Haskell, for example, lets you have Go-like coroutines and channels. But it also lets you program with software transactional memory, or use other parallelism constructs.
Also, the inability to specify invariants of your program isn't flexibility. The ability to specify them or opt out of specifying them, which is what strong type systems give you, is.
1. https://www.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/EWD667.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/E...
- briantakita 12y ago> It explains how natural language is a very poor way to express programs, and how it held back science and progress for many centuries. I'm not interested in using natural language to implement the software (write code). I'm interested in using natural/technical language to create an ontology for the architecture. This is where things get gray. When I think of an architecture, I think of something that evolves over time. I think of architecture as a tool to facilitate communication between programmers, designers, project management, domain experts, & users. This ontology evolves over time as the software, understanding of the domain, & the domain itself changes. I see this fuzziness as an accurate model of the conceptual domain, which is ultimately based on the understanding of multiple humans. This understand is fuzzy and heavily dependent on context. And yet, the ontology attempts to coral this fuzziness into more strongly defined concepts, which map to the implementation. The implementation should not be fuzzy at all. > Other invariants are similar. Instead of documenting them or keeping them in your head, you let your compiler worry about them. I usually use guard clauses to protect against nulls. I rely on my tests & production monitoring systems to prove that the implementation is incorrect. When there is such proof, I correct the system. In environments that support rapid feedback & deployment, like the web, this works well. In environments that don't support rapid deployment, iteration, and where lives are at stake, not so well. > But Go is extremely inflexible. It has a very primitive set of tools to do everything, clumsily. A language like Haskell, for example, lets you have Go-like coroutines and channels. But it also lets you program with software transactional memory, or use other parallelism constructs. That sounds good to me. > Also, the inability to specify invariants of your program isn't flexibility. That mostly sounds good. I would want invariants to be optional, which sounds like is the case.
- Peaker 12y ago> This ontology evolves over time as the software, understanding of the domain, & the domain itself changes. So what does this have to do with Go or type systems? > I usually use guard clauses to protect against nulls. I rely on my tests & production monitoring systems to prove that the implementation is incorrect. And that's a bad thing. There are better tools for this job. What's the downside of encoding nullability into the types? > That mostly sounds good. I would want invariants to be optional, which sounds like is the case. Every good type system lets you "opt out". Therefore, it is a bit silly to look at dynamic typing, where you cannot "opt in", as more flexible.
- briantakita 12y ago> This ontology evolves over time as the software, understanding of the domain, & the domain itself changes. > So what does this have to do with Go or type systems? I've found that type systems, that aren't utilizing Duck Typing, as being restrictive & causing incidental complexity when evolving the design. I don't really care if something is a categorization of something else. I usually (> 98% of the time) only care if that something adheres to an interface. I don't like to label people in life either :-) > I usually use guard clauses to protect against nulls. I rely on my tests & production monitoring systems to prove that the implementation is incorrect. >And that's a bad thing. There are better tools for this job. What's the downside of encoding nullability into the types? For the web, it's not that bad. The design is constantly evolving, so most of the development period is spent completing something that is not finished. There's no downside in encoding nullability, unless extra syntax & incidental complexity is added. It's not a big problem for me so I'd rather not have to do extra work for this feature. > That mostly sounds good. I would want invariants to be optional, which sounds like is the case. > Every good type system lets you "opt out". Explicitly or implicitly? I'd rather be opted out by default and opt in when I want to. Again, I don't want to do extra work or have incidental complexity.
- Peaker 12y ago> I usually (> 98% of the time) only care if that something adheres to an interface. Well, whether something is "nil" or not definitely matters to whether it adheres to the interface, doesn't it? > There's no downside in encoding nullability, unless extra syntax & incidental complexity is added You just need sum types and pattern-matching, which are a straight-forward addition to the language -- and very fundamental to computation, so not quite "incidental complexity". > I'd rather be opted out by default and opt in when I want to Then why do you use Go and not a fully dynamically typed language? In Go you opt out explicitly with "interface {}". Why would you rather opt in? Opt out makes sense because types are so cheap 99% of the time.