# True interactive development

**URL:** <https://discourse.julialang.org/t/true-interactive-development/67318>\
**Category:** Internals & Design\
**Tags:** debugging\
**Created:** [August 30, 2021, 12:38am UTC](https://discourse.julialang.org/t/true-interactive-development/67318 "2021-08-30T00:38:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [August 30, 2021, 12:38am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/1 "2021-08-30T00:38:05Z")

</div>

I stumbled upon [this blog](https://hyperthings.garden/posts/2021-06-20/hell-is-other-repls.html) while casually scanning hacker news.

So I thought Julia REPL + Revise is top notch until it described “true interactive development” as follows:

> True interactive development is also about programming in such a way that your program never crashes. Instead, whenever an unhandled condition is raised, the program starts an interactive debugger. While interacting with the debugger you don’t lose _any_ program state, not even the ephemera of the call stack, unless you choose to do so.

I have never used Common Lisp but that sounds really cool to me. I could imagine that when I encounter an undefined variable or unknown method that got called, and then I just define it immediately and continue computation.

Has anyone thought about doing something like that with Julia? Would you think that is useful?

---

<div class="post-metadata">

**Author:** ![Paulo\_Jabardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulo_jabardo/32/3196_2.png) [@Paulo\_Jabardo](https://discourse.julialang.org/u/Paulo_Jabardo)\
**Post date:** [August 30, 2021, 2:02pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/2 "2021-08-30T14:02:10Z")

</div>

Someone mentioned a few days ago how they missed the programming environment in the lisp machines and how everything was downhill from there. I think that may be one things he misses…

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [August 30, 2021, 3:16pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/3 "2021-08-30T15:16:53Z")

</div>

> [@tk3369](#):
>
> Would you think that is useful?

Oh yes, immensely useful. We get that in Matlab.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [August 31, 2021, 5:25pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/4 "2021-08-31T17:25:09Z")

</div>

There are a lot of things Revise can’t do currently. Among the most disruptive is the inability to redefine structs.

See also:

> [@Feature request: REPL mode for debugging](https://discourse.julialang.org/t/feature-request-repl-mode-for-debugging/66926):
>
> Wouldn’t it be great to have a REPL mode that’s optimised for debugging rather than ultimate performance? Or maybe it has some experimental features that can be turned on at the user’s own risk? Some features that might be useful when debugging at the cost of some potential performance loss: Avoid optimising IO code for faster printing Method selection and type inference while the user is typing the commands! For example if I am typing println(x) and x is a vector of floats, before typing ) an…

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [August 31, 2021, 7:12pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/5 "2021-08-31T19:12:31Z")

</div>

That’s very different and something that Debugger can already do — see “breakpoint on error” in the docs. Common Lisp supports fixing the implementation of your program from the debugger and continuing to run it with the fix. Which is cool but has always struck me as a bit too fancy and still doesn’t save you from needing to restart your program in all cases. What if, as often happens, it’s too late by the time you actually get an error and the mistake that caused the error has already been made and cannot be fixed by unwinding the stack? Does “true” interactive development then dictate that one be able to rewind the program execution and undo what has already been done? Of course, that can be done with rr, which is often billed as a “time traveling debugger”, but it seems like Common Lisp draws the line in the sand for “trve interactive develop\m/ent” at the location that they happen to be able to implement easily because of the language’s error handling model (which _is_ exceptionally powerful). I’d rather see good Julia-level integration with rr and the resulting ability to walk backwards and forwards through a debugging session.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [August 31, 2021, 8:09pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/6 "2021-08-31T20:09:22Z")

</div>

I don’t think so. You can’t just fix the code and continue running.

---

<div class="post-metadata">

**Author:** ![banksiaboy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/banksiaboy/32/27032_2.png) [@banksiaboy](https://discourse.julialang.org/u/banksiaboy)\
**Post date:** [September 2, 2021, 9:02am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/8 "2021-09-02T09:02:12Z")

</div>

In Smalltalk we often did development directly in the debugger. Write a use-case as plausible source. If there was a ‘does not understand’ error - meaning there was no implementing method on the object. We’d pop a menu up to create a boiler-plate method on a relevant class. The boiler-plate method raised a 'not-implemented-yet exception, so you would run past it in the debugger.

You could restart, or re-run from anywhere on the stack. Best environments I’ve worked in. [Alto System Project: Dan Ingalls demonstrates Smalltalk - YouTube](https://www.youtube.com/watch?v=uknEhXyZgsg&ab_channel=ComputerHistoryMuseum) Dan’s the Man. just watch the environment No better refactoring environment than a modern Smalltalk.  
Worth noting that the ProcessScheduler, and Debugger are all written in Smalltalk

I’m really enjoying Julia…

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [September 2, 2021, 4:47pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/9 "2021-09-02T16:47:42Z")

</div>

Yep, Smalltalk and Common Lisp really set a high bar here. It would all be cool stuff to be able to do.

---

<div class="post-metadata">

**Author:** ![pyrex41](https://avatars.discourse-cdn.com/v4/letter/p/4bbf92/32.png) [@pyrex41](https://discourse.julialang.org/u/pyrex41)\
**Post date:** [September 3, 2021, 4:51am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/10 "2021-09-03T04:51:35Z")

</div>

Smalltalk’s influence on language design and the discussions thenceforth is pretty unique imo. It’s relationship to the rest of programming is something like the relationship academia claims to have relative to the “real world”, but always falls short of.

---

<div class="post-metadata">

**Author:** ![banksiaboy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/banksiaboy/32/27032_2.png) [@banksiaboy](https://discourse.julialang.org/u/banksiaboy)\
**Post date:** [September 4, 2021, 12:31am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/11 "2021-09-04T00:31:22Z")

</div>

OTI who I worked for for a while, built a very good Smalltalk and configuration management system, they did embedded software for hospital heart monitors, military fire-control systems, police radio systems, nuclear power control systems, machine production configuration for wafer-fab, Tektronix had Smalltalk in their top of the line oscilloscopes. Smalltalk was killed when IBM and Oracle pumped all that money into Java, and stole all the engineers responsible for JIT. The first and probably still the best IDE for Java ‘VisualAge for Java’ was written in IBM/OTI Smalltalk. IBM bought OTI, and redirected them into Java.

[Answer to Is Smalltalk a programming language that is actually used in the corporate world? by Eliot Miranda](https://qr.ae/pGerC6)

[You Can’t Do That With Smalltalk](https://www.slideshare.net/esug/you-cant-do-that-with-smalltalk) — Dave Thomas

---

<div class="post-metadata">

**Author:** ![banksiaboy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/banksiaboy/32/27032_2.png) [@banksiaboy](https://discourse.julialang.org/u/banksiaboy)\
**Post date:** [September 4, 2021, 8:12am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/12 "2021-09-04T08:12:01Z")

</div>

It’s a pleasure to be learning Julia. lovely work!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 4, 2021, 8:14am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/13 "2021-09-04T08:14:57Z")

</div>

As much as I love Common Lisp, I think that this is a misfeature as it encourages tinkering with the state of the program as opposed to making sure that everything is ultimately kept in source code files with proper test coverage. Fixing methods on the fly in the debugger/REPL and forgetting to introduce the change in the source is something that can easily happen.

I would rather

1. have the program fail,
2. inspect the stack,
3. figure out the problem
4. (may do some refactoring)
5. write some unit tests
6. and restart.

Another related CL feature is [restarts](https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html), which essentially amounts to using conditions for “regular” control flow. Very sophisticated, but ultimately encourages bad design.

---

<div class="post-metadata">

**Author:** ![banksiaboy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/banksiaboy/32/27032_2.png) [@banksiaboy](https://discourse.julialang.org/u/banksiaboy)\
**Post date:** [September 5, 2021, 4:05am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/14 "2021-09-05T04:05:09Z")

</div>

The ENVY/Manager configuration management system we had in OTIs Smalltalk had an immutable database for source, and byte-codes, you could create a scratch for local tinkering but once stored, it was totally identified by hash. Anyone could do bit-accurate builds of a named configuration from any repository anywhere. First and second gen Smalltalkers tended not to like it. They preferred hand-crafted change-sets. I used make a living out of moving change-set based development efforts into ENVY. The weekly build effort would go from a three-day horror show, using your best engineer, to half an hour on Friday afternoon that we could take turns at. I don’t think continuous build and test was a thing then.

I really like using the Julia package system, just seems right. I haven’t done anything at scale though.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [September 5, 2021, 4:58am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/15 "2021-09-05T04:58:19Z")

</div>

ENVY sounds like a good solution. Was it possible to see the source and diffs between versions for those snapshots.

---

<div class="post-metadata">

**Author:** ![banksiaboy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/banksiaboy/32/27032_2.png) [@banksiaboy](https://discourse.julialang.org/u/banksiaboy)\
**Post date:** [September 5, 2021, 6:13am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/16 "2021-09-05T06:13:20Z")

</div>

Yes there was quite good facilities for comparing and merging various structures.  
This [Envy FAQ](http://www.faqs.org/faqs/smalltalk/ENVY-faq/) is the best I can find at the moment. I can probably strip some noise from it. I worked with it as a customer, and as an engineer on the product. Some of the ideas in the ENVY/Packager which was used to build the stripped down runtime were from my fevered brain. There was a very good team at OTI - of which I was a small part, for a relatively small time.  
I think there are some relevant ideas that might adapt to Julia’s structure. As the kungfu master said ‘ask me the right question, and I will ring like a bell’, though it is something like 20-30 years ago…

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [September 5, 2021, 11:04am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/17 "2021-09-05T11:04:58Z")

</div>

I agree with everyone that says it’s a misfeature, but as @tpapp put it, the ability to do

1. have the program fail,
2. inspect the stack,
3. figure out the problem

immediately whenever there’s an error is immensely powerful. Having to load Debugger.jl and rerun in slow mode really takes the wind out of my sails 🙁 enough that I basically never use it. I’d rather do print/global-variable debugging than use Debugger and risk waiting a long time or introduce some change in behaviour that changes the error.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [September 5, 2021, 4:10pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/18 "2021-09-05T16:10:15Z")

</div>

as I understand it the whole restarts / edit live code thing can be immensely helpful on stuff running 24/7 far away (in a telecom server closet or a rover on Mars for example). But I agree it’s not worthwhile when you’re talking stuff you can debug on your desktop machine.

[https://flownet.com/gat/jpl-lisp.html](https://flownet.com/gat/jpl-lisp.html)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 5, 2021, 5:19pm UTC](https://discourse.julialang.org/t/true-interactive-development/67318/19 "2021-09-05T17:19:34Z")

</div>

I don’t really understand what is meant by ‘misfeature’ etc. here, but I can say from long experience that changing the program state interactively and updating the source during runtime is _immensely_ powerful and useful. _Of course_ you can misuse it or make mistakes, like with _any other_ feature.

It is one of the truly good features of Matlab.

If this were combined with a ‘time traveling’ debugger, it would be an absolute _killer_ feature.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [September 6, 2021, 5:36am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/20 "2021-09-06T05:36:35Z")

</div>

> [@Tamas\_Papp](#):
>
> Another related CL feature is [restarts](https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html), which essentially amounts to using conditions for “regular” control flow. Very sophisticated, but ultimately encourages bad design.

This seems to be a wise warning and I’ve seen similar points by others. However, the first thing a programmer learns is that warning is to be ignored. So I made one in Julia: [GitHub - tkf/Restarts.jl](https://github.com/tkf/Restarts.jl)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 6, 2021, 7:52am UTC](https://discourse.julialang.org/t/true-interactive-development/67318/21 "2021-09-06T07:52:33Z")

</div>

> [@DNF](#):
>
> updating the source during runtime is _immensely_ powerful and useful

agreed, the misfeature here is encouraging working on the image _without_ making changes in the source code.

> [@banksiaboy](#):
>
> I think there are some relevant ideas that might adapt to Julia’s structure.

I am not familiar with ENVY, but I would prefer if Julia kept it simple. Specifically,

1. the source code, as read from the filesystem, is the source for all definitions
2. let’s make updating from this really convenient and automatic — [redefining structs](https://github.com/timholy/Revise.jl/issues/18) would be enough for me, but if people want to be able to do this while in a debugger, that’s useful too
3. source code should be managed as files, with version control.

[Next page](https://discourse.julialang.org/t/true-interactive-development/67318.md?page=2)
