11 ms·
No one in this thread is yet talking about the content of this talk, which I think is interesting. Rich is doubling down on dynamic typing. As the world is grad
by hellofunk 9y ago
No one in this thread is yet talking about the content of this talk, which I think is interesting. Rich is doubling down on dynamic typing. As the world is gradually moving to more statically-typed languages (Rust, Swift, Go, Elm, Purescript, Typescript are all popular tools that come to mind), Clojure remains in the embrace of dynamic typing, and this talk is an interesting look at the perspective of why that is, and adds perhaps a little bit to the debate between static and dynamic typing.
I admire Rich a lot, but I also admire John Carmack, and it is apropos that yesterday another comment was shared on another post here [0] about his opinions on static typing, and how in just a few years (his talk was in 2013), the industry as a whole has made considerable changes in its opinions of static typing; according to his talk, in 2013 most of the industry was still not convinced of the benefits of static typing.
[0] https://news.ycombinator.com/item?id=15460604 https://news.ycombinator.com/item?id=15460604
- amelius 9y agoOkay, but at least with static typing one can have dynamic typing simply by using an all-encompassing type. With only dynamic typing, one cannot have static typing.
- hellofunk 9y agoI invite you to watch this talk. Dynamic typing is about a lot more than having an "Any" type. It's about widespread lack of extra code and cognitive overhead associated with the imposed structure of adding static types to a project, as well as the verbosity that static typing typically adds (including in type-inferred languages). You can't just turn off the static typing in a static-typed language; you can turn off the static type for a specific type, yes, but that doesn't give you the experience that dynamic languages offer.
- amelius 9y agoYes. So how about a workflow where you write dynamically typed code, and then use a tool to convert that code (with user input) to statically typed code. You could do this incrementally. So once you have "frozen" your code into statically typed form, you could add dynamically typed code to it, and then "freeze" that. Or you could "thaw" the whole codebase, and add dynamically typed code, etc. > You can't just turn off the static typing in a static-typed language I suppose one could design a language where that is possible (although you wouldn't use the full power of static typing in that case).
- zimablue 9y agoI think the thing is that you write code in dynamic languages that you would never think to write in typed languages because it's just too against the culture/grain. Two common situations in my job of throwing data around: Dataframes and pivoting- here the type of a thing (its columns) is never going to be easily statically provable because operations modify it dynamically. Reactive/dataflow style programming- look at the python MDF library, you annotate functions and it dynamically infers a dataflow graph from your code. You can do dataflow in typed languages but nowhere near as elegantly normally. These two things are core to what I do and drive a train through a typesystem. I think that the best possible solution would be to have some way to embed proofs and individual typesystems in different parts of your program, like a dynamic language with plugged proofs and types not a single typesystem language that you sometimes go around or switch off.
- sooheon 9y agoHow much experience do you have with clojure.spec? I see it as a way to add dependent-type-like functionality to parts of Clojure, so my impression is that it addresses your final need very well. But if you know more about it than me and disagree, I'd like to know.
- _dps 9y ago> Yes. So how about a workflow where you write dynamically typed code, and then use a tool to convert that code (with user input) to statically typed code. This describes how I do a lot of my work. I prototype quickly in Python or Lua, and I have some in-house tools that let me migrate highly constrained subsets of those languages into C, with automated Quickcheck-style checking to make sure the translated code generates the same log messages as the source code. For me the experience of starting out with something extremely flexible, with a repl, easily mocked components, and tons of "kitchen sink" functionality makes me feel free to experiment quickly. Once I have something that looks like it's working I iteratively remove reliance on dynamic features or built-in libraries. At the end I have a Python function that looks a lot like a C function, but I got to that function a lot faster and more comfortable than I would have had I started in a pure C workflow. And from there, it's a quick build step to convert that function to a C function. I haven't found a good common name for this pattern, but I think of it as "plastics and metals", analogous to industrial design. Even though you know a component will end up being made of steel, lots of the design questions are more easily and cheaply solved by making a similar thing in plastic. The plastic of course won't stand up to "production" load, but it usually doesn't have to do so.
- stewbrew 9y ago(I haven't watched the talk because nothing you said makes me expect hearing something new.) WRT verbosity and cognitive overload: I honestly challenge this statement. In a modern statically typed language, you have to add a few type annotations here and there but in exchange you can skip most runtime checks (and sometimes nullity checks). You don't have to remember the type of a variable because the compiler can tell you. I admit dynamically typed languages are nice for interactive exploration in the REPL but that's about it. Too bad typed clojure didn't become the mainstream closure.
- hellofunk 9y agoThe cognitive overhead is really not about type annotations. It's about program structure. If you watch the video, I think there are some good points made.
- gw 9y ago> I admit dynamically typed languages are nice for interactive exploration in the REPL but that's about it. For Clojure programmers, "interactive exploration in the REPL" is the primary way we write programs. So, if one admits that dynamic typing is ideal for this, then making Clojure dynamic was the right choice.
- stewbrew 9y agoNo, because you usually have to maintain programs, add features later on, rewrite/refactor parts of the program. Do you write only one-off scripts?
- gw 9y agoI must emphasize that any time we "maintain programs, add features later on, rewrite/refactor parts of the program", we are doing so with a REPL. We don't just use the REPL for one-off scripts.
- sbov 9y agoAs someone who recently moved to Clojure, REPL based programming is a completely different experience. It isn't like using python's REPL.
- lucozade 9y ago> imposed structure of adding static types to a project I'm sure you didn't mean it this way but, for me, I think I reach for my pet dynamic or static typed language depending on whether or not I'm expecting to think about the structure of the program up front. Typing is not something I've thought of as an addition. If I'm doing something small or I'm expecting to iterate around some ideas/play with some data, then a dynamic language lets me try things out sooner. If I'm expecting to spend a fair amount of time on the project or I need to think hard about how I'm going to achieve stuff then thinking about the types up front is valuable. I'm likely to go for a statically typed language. I also have a bias towards statically typed if the project is going to get large. This is because I've tended to have more serious problems with large dynamically typed codebases. But I appreciate this is a bias; there are many factors that affect maintainability.
- agumonkey 9y agoI'd add one thing. The way we structure "logic" in subpart of systems is often one or nothing, while quite often we could check parameters by necessity. F a b c d can be valid if called in F a b c d e f g, because F gets what it needs (a b c d), the rest can be ignored. Like an implicit subclass relationship. A subclass B of A can have more features, but as long as it is an A, something depending on an A can enjoy it. Of course this can cause issues (stack use in function application with unnecessary information, albeit a non naive interpreter/compiler could prune this). In the end we spend a lot of time circling things around for safety, when we could have something more relaxed and thus more resilient.
- tim333 9y agoBy the way he doesn't get to static types till 1:06:06 out of a 1:15 talk - there's a lot of other stuff.
- ludwigvan 9y agoI love Clojure and dynamic typing and actively use it in one of my commercial projects. However, my observation as an instructor is that static typing fixes a lot of issues in day-to-day coding of average (boring) projects, especially in projects where the average caliber of the programmers is low. It is not that it prevents bugs per se, but makes the creation process much smoother for people via instant feedback that the code won't work/compile at all.
- sanderjd 9y agoI believe it also fixes a lot of issues in day to day programming of non-boring projects where the average caliber of programmers is high. The "me and my team are too smart and our project is too interesting to benefit from static analysis!" meme is silly.
- Hupriene 9y agoIt's less about being smart and more about having habits that fill in the gaps that a lack of static analysis leaves. This can happen through TDD or through REPL driven development. Each has their own strengths and weaknesses.
- sanderjd 9y agoREPLs are super nice, TDD is super useful, but neither of them either preclude or obviate the advantages of static analysis. Although in practice, none of the popular statically typed languages has a standard REPL (except maybe TypeScript?) which is really a shame. But I agree with you that it has nothing to do with smart vs. less smart.
- throwaway7645 9y agoOn the other side of the coin, static typing doesn't catch a lot of things that TDD & REPL development can, although nothing prevents you from using tests with static typing.
- Jach 9y agoI think it's important to note Carmack also tried Racket after that, even wrote a server that was in production for a while. As I recall from his twitter feed he really likes it especially for beginners (got his son to make games with it) and especially for getting things done as a beginner to the language. Later he discovered Typed Racket and appreciated it, I remember something about with proper types at least at the interface level he found some design flaws to fix. Just like some people think dynamic types are limited to the subset of static types with Any type for everything and think JavaScript is a great example of its utility and power instead of e.g. Common Lisp, a lot of people think static types are limited to what you get in C++98 instead of e.g. Haskell. The type flame threads would be a lot more interesting if people had tried using more than the most popular representatives of each side before forming opinions...
- kenshi 9y agoI think its a mistake to directly compare the experiences (and conclusions) of these two exceptional programmers. Rich Hickey explains at the start of his talk where he is coming from, what the context of his development work, and he calls it "Situated Software". His background and the context for his development is building information systems in organisations where the rules are messy and no doubt change often. One of the things he calls out explicitly in his talk is the messiness of dealing with the "Two for Tuesday" rule in one of the systems he worked on. He also spoke about how different working in that domain was, to doing compiler development. John Carmack's experience and domain expertise is building high performance game engines. I'd argue this is closer to compiler writing in the sense that it is a much more rigid problem than say having to serve the needs of an organisation whose requirements may change often and in seemingly arbitrary ways, and usually on a tight deadline. I am not trying to elevate one domain over the other. They are different kinds of problems, and have different kinds of limitations and constraints applied to them. As such I don't think its any surprise that the priorities for each of these developers is different. Choosing between more dynamic or more static approaches without considering the context in which you are working in, is a mistake.
- mightybyte 9y agoThis is an outstanding point. When watching this talk, I got the distinct impression that Rich has simply worked on a very different class of problems than the ones I have worked on. As we all are wont to do, we extrapolate our experience to the whole universe. But that's not always the right thing to do. I would say that for the most part, a statically typed language can do the same things a dynamic language can do, but not the other way around. Another commenter mentions the Any type, but I don't think that's it. It's maps. Rich wants to be able to combine maps with a union operation, take subsets of keys, etc. And that is exactly what maps afford. I'd rather work in a language like Haskell where I can use strong types when I need them and drop down to untyped maps when I need them than a language like Clojure where all I ever have is the maps. 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. I'd rather work in a language where my compiler can help me this way than in one where it can't.
- ceronman 9y agoStatic vs Dynamic typing... Why one has to win? I don't think it's about being convinced of benefits of one or another. We need to be convinced about the drawbacks of each approach. Then we will understand that there is no silver bullet and each kind of language has strengths and weaknesses. I love static typed languages. I love that they show me silly errors as soon as I type them on my IDE. I love that I can get auto complete and automatic refactoring tools. I love that I can easily jump from one function to another by just clicking on their names names as if they were hyperlinks. I also love dynamic typing. I love how few lines of code you need to do some complex tasks. I love how easy is to manipulate complex structured data coming in JSON, YAML or XML forms. I love how easy is to do metaprogramming with them, how easy is to create your own DSL and make tasks like DB access a piece of cake. I love how you can just REPL into your server running in production, change things, test them and leave. I like that we have both kind of languages. I chose static typing for some projects and dynamic for others. I hope no paradigm wins. Let us the best tool for the job.
- he0001 9y agoFor me static typing is one less thing to think about and I can concentrate on the problem.
- hellofunk 9y agoIronically, those who prefer dynamically typed languages would make the exact same argument.
- throwaway7645 9y agoYea as someone who really learned coding in a dynamic language, static typing drives me bonkers and makes me think about things I'd rather ignore. I know static typing has many advantages, especially when coupled with an IDE, but I don't want that. I only really need a REPL to test out snippets and a text editor to assemble them into a coherent program before feeding it to the compiler. Well, that and Stack Overflow. Some of my ideas might change if we're talking about a large project though as I mostly code for task automation, data analysis, and helper scripts.
- s_kilk 9y agoI think it's interesting that Rich seems to miss out on Erlang (and Elixir) entirely, even when he gets to talking about Situated Programs and Runtime Tangibility, not even to speak of Concurrency.
- erokar 9y agoElixir seems very similar to Clojure to me (the former being influenced by Clojure).
- s_kilk 9y agoAbsolutely, (I moved over to Elixir from Clojure) and hence it seems like a strange blind-spot. When Rich talked about Systems programming and Runtimes, I expected Erlang/Elixir to come up as obvious examples along with Smalltalk and Common Lisp.
- christophilus 9y agoI'd love to read a writeup on your experience doing this. I love Clojure, and really don't like the Elixir syntax (though I used to dislike the Clojure syntax, so...) Have you found Elixir's oddities (like calling lambdas in a different way than you call functions lambda.(:bar) vs func(:bar)) to be annoying?
- erokar 9y agoChiming in here, having only dabbled with Elixir for a couple of months. My gripes: - Calling lambdas with a dot is a real wart. I find it very easy to forget and it looks ugly. - I also don't like the Rubyesque end keyword you have to provide for functions. Get's verbose. Whish Elixir was white space sensitive like Python, Haskell, Elm et al. - Pattern matching in functions is an idiom that is overused. It easliy gets verbose since you have to type out the full function signature. - A proliferation of data structures dictated by performance issues (lists vs. tupels, maps vs. keyword lists). Ugly map litteral: %{}. (Personal issue I guess, I tend to find $%& etc. ugly in a programming language. It's swearing at me!) Apart from these gripes I like Elixir a lot. A clean and pretty simple language. Protocols are used in a nice way to acheive polymorphism (similar to Clojure, I think). Good as a first FP language. Gives you access to an interesting runtime.
- flavio81 9y ago>As the world is gradually moving to more statically-typed languages Depends on how do you see it; because Python has grown a lot in the last 2 years, and Javascript (pure) is still growing. And don't discount Julia; i can foresee good future for it.
- jhbadger 9y agoExactly. Static typing isn't some new technology -- languages like Pascal (which was very popular in the 1970s and 1980s) had it. Scripting languages (which tend to be dynamically typed) took off in the 1990s as a reaction to the inflexibility of statically typed languages. If static typing was really the silver bullet its current defenders think it is, why do they think scripting languages took off?
- bbatha 9y agoBecause the static languages of the time, C++, Java, etc had serious deficiencies that made that style of static typing a hindrance. Type inferences, type class style generics, and gradual typing have been huge wins for the ergonomics of static typing. Additionally IDEs have improved immensely since the 90s and static typing makes the experience much better. Finally I’d argue that the size of apps has increased a lot. Dynamic typing is great for small apps that you need to get out the door. Static typing shows its advantages in the long tail. The more people you have working on a codebase the more the static typing pays off. Typescript for instance was created specifically to manage large JavaScript code bases.
- flavio81 9y agoReally big apps have existed since the early 70s. I'd argue that the average application size gets lower every year due to the increasing number of specialized libs every year. And C++ has supported generics long before the boom in popularity for dynamic scripting languages...
- erokar 9y agoHis argument that static typing introduces coupling and reduces modularity is convincing. His argument that Java's Spring framwork is little more than necessary dynamism forcing its way back into a statically typed language was eye opening to me. Certainly an interesting talk.
- _pmf_ 9y ago> His argument that static typing introduces coupling and reduces modularity is convincing. It's absolutely bogus. In Java, C#, C and C++, I can pull in dependencies via scanning a plugin directory that searches for JAR resp. DLL files. The only coupling is the interface, which in a properly factored system will be a single module containing only the related set of interfaces. Claiming this exposes the author of never having worked on any actual medium or large system in any commonly used static language. (Maybe the more academic ecosystems like Haskell or ML require implicitly pulling in dependencies via textual imports, but this is absolutely not the only way to do it.)
- kbutler 9y agoClojure is a reasonably sized system written in Java.