Watched the video of this on YouTube. Overall a great talk, though I don’t agree with many of his conclusions. He seems to argue that ‘move fast and break things’ is the way forward, and that big dynamic runtimes allow for this with great runtime debugging etc. I prefer to catch my bugs at compile time, and have found this to be a far more reliable path to actually finishing a software project.
I think more he was saying that types don't help you not break things, your preparation is worthless, you're not actually helping bugs, and when something does break your far slower at fixing it.
So not "move fast break things".
More "Don't over prepare, fix things fast."
The only thing I don't like about all these people talking about types is when you need to make a program change and that change has large impacts on other areas, like in a core API.
I do not want to make a change in a core API and have my program build without me addressing all of the places that would be affected by that.
This is where types shine, and this is where I think types are important.
If a language abandons types that is fine, the dynamic possibilities are amazing and I'd love to have them.
But I will not give up that ability to make a refactor in core code and then turn be able to address all of the places that that change breaks things.
Am I wrong in that?
Is my desire to do this just rooted in my own bad programming habits?
> I do not want to make a change in a core API and have my program build without me addressing all of the places that would be affected by that.
> This is where types shine, and this is where I think types are important.
This is also where tests shine, which are far more expressive than the type systems we have today. Tests are usually not as convenient as types though, but it's another parameter to consider when choosing the right solution for a given scenario.
> But I will not give up that ability to make a refactor in core code and then turn be able to address all of the places that that change breaks things.
This will be less satisfying since it's anecdotal, but I'll offer up my experience anyhow: I rarely find myself refactoring. When I do refactor, it's almost always in the "changing the factoring" sense, in that callers are none the wiser to changes since the interface is the same, which limits the fear of breakage. That's not to say that it always turns out this way, but churning regularly on interface boundaries would be a "smell" to me.
To further beat the drum from above, I'd additionally expect the tests to help prevent breakage whether the program's dynamically or statically-typed. I review plenty of code, much of it in Scala, which puts a heavy emphasis on its strong typing. When there aren't tests, I request them or write them myself, and that uncovers bugs more often than not despite the programs passing the type checker.
You’re not at all, and it’s one of the main reasons that I feel confident hopping into a codebase that I’m not as familiar with in something like Rust than say Ruby or JavaScript. The lack of strict types makes understanding how a program works very difficult, and being told this by the compiler or interpreter all but impossible.
I didn't get that from the talk. What the author meant (I'm also extrapolating from advocates of dynamic languages) is that quality increases with iteration. By changing and running your program, you can find edge cases you hadn't thought about and modify it to make it testable, modifiable, easy to inspect/visualize, etc. An environment that reduces friction required to tinker with a programs allows you to make them robust too - if you so wish. If you just want to play, then you're free to do that too (and the creative process benefits from being able to do so).
I'm not advocating for only using this workflow, ideally we could add types too. Compilers can enable an iterative workflow (Elm comes to mind), but I find myself sprinkling types as I go exploring how my program will accomplish the task (TS without strict).
The pendulum has swung to type-everything-first and I'm not sure it's the silver bullet we're looking for.
I watched the talk last week, so perhaps my memory's a bit off, but "move fast and break things" was not the takeaway that I got. I thought of it more of "problems are going to happen, being able to debug them is important, and there are better tools available for dealing with that than what's common".
Additionally, I don't recall if he said it in the talk, but it's been my experience that type-based bugs often surface early and are generally incredibly cheap compared to other classes of bugs (functional bugs, logic bugs, security bugs, etc.).
It's also just the wrong place in the stack to add these features. It's not a language concern, it's a platform concern. If I'm running a program in a web browser, it doesn't matter what language it's written in, I can pause the program and interactively explore it via the browser console. We should have the same thing for native apps on operating systems in general, and they should be native to the OS (provided by the OS vendor themselves) and not require any modification to the program (or any special programming language) in order to use.
I agree this would be very cool. I can’t count the number of times I wish I had runtime interactive debugging in a repl along the lines of pry in Ruby in just about every language that doesn’t have it.
That said, gdb etc are pretty awesome too if it’s an option
History has proven the exact opposite, as the failure of Smalltalk and the ascendancy of the web browser demonstrate. And as I assert, Dan Ingals is incorrect.
Last time I looked into it, the Web browser is a OS agnostic platform and JavaScript influence in tooling traces back to Smalltalk via SELF influence.
There are even two Smalltalk like development experiences Web browser based, Amber Smalltalk and Lively Kernel, the latter from Dan Ingals.
The OS should be an implementation detail of language runtimes, as proven by serveless computing and cloud native development, who cares if those runtimes run on top of an OS, bare metal or a type-1 hypervisor.
Agreed on static type checking - I also consider it extremely important. However I don't see it as being incompatible with the philosophy of live programming. Smalltalk relies a great deal on dynamism, but I believe it would be possible to create a language and environment that both enforces static typing and supports live programming + persistence. It's an open research problem though.
In web, I’d kill for a way to debug an error by replicating user’s state and play back actions and requests while stepping through an uncompiled version of the application running. I think I could solve bugs into infinity if I had that kind of power.
This kind of thing shouldn’t even be difficult, yet I have never been anywhere that has this kind of live code retrospection.
Fulcro (a library for Clojure/ClojureScript web applications ) has a way of doing this, and I'm sure it's not unique in this aspect: I just don't do enough work in this space to be familiar with the other offerings. This type of feature is valued in the Clojure community, so I wouldn't be surprised if reagent has something like this as well. And this type of thing isn't unique to Clojure, either.
Ironically one of my major annoyances in debugging Clojure is that stack traces don't come with a program state that can be inspected (as you get in ELisp or GDB)
I'm probably missing some subtlety. I'd think you could have some "debug mode" layer where the Clojure runtime catches exceptions. Basically wrapping every exception in Clojure with a try/catch, and doing a try/catch on every interop call
It's not ideal having two different modes (like a C++ Release/Debug) - but it'd be better than the current situation
Maybe this is what CIDER's debug macro is actually doing - I always forget to play around with it :) I'll need to try it in the future.
btw, thanks for your work. I really appreciate the stuff you've shared and it's nice to know someone else also uses thing/geom :))
Has the highly decoupled "mini-library" thing/geom architecture influenced Clerk? I'm been meaning to try it out - but notebooks always feel like they come with some ecosystem lock-in (esp if it's a company trying to make money - ie. Nextjournal). It'd guess it's part of why everyone reverts back to plain text. With thing/geom I just pick and choose and tweak the pieces I need - and then swap them out when I want to change to something else entirely (mostly for building GUI applications in CLJFX)