Need help?
<- Back

Comments (63)

  • dieggsy
    As a Common Lisp developer, the intro about Lisp strikes me as sort of mostly(?) true.I would say in my experience we do actually "compile and execute" code, we can just do this incrementally and with less context switching because of the described workflow. But quite often there are in fact separate compile and run steps, it's just not at the whole program level (say, compile a function and run it or a calling function).And despite how often it's shown off as a strength, redefining code during actual execution isn't quite that common, I think. Yes, it is done sometimes, but lots of programs don't really fit that paradigm in the first place. It can work well for e.g. some games or long running servers.As for working in an image without source code: this seems like a terrible idea. You might do this for trivial, one off experiments, but in general you benefit from writing out and organizing your code early. I'm not even aware of a particularly easy or clean way to write out source code from an image as described. It could be done, but all the ways I can think of sound like more of a pain or mess than anything. Could just be my experience or I'm missing some neat feature of a commercial Lisp or something.
  • cassepipe
    Note exactly the same but worth mentioning for C/C++ programmers out there: gdb can actually function as some sort of "cheap" live environment for C and C++When stopped at a breakpoint, you can evaluate C/C++ expressions, modify state, call functions, and, with compile code, have GDB compile and execute new C/C++ code in the context of the running process: (gdb) set variable state->counter = 42 (gdb) call recompute_state(state) (gdb) compile code > printf("counter = %d\n", state->counter); > do_something(state); > end That makes for a surprisingly nice "REPL attached to a running C program" experience. You can poke at the heap, change variables, call into the existing code, and inject little bits of new code without restarting the process.One use case I have fond memories of was implementing different trees structure and adding a print_dot function that printed the tree in .dot format and whenever I call the function from inside gdb, the xdot window would redraw with an updated tree graph.I know it isn't really the same thing as a Lisp image where the injected code is become persistent but still nice to haveP.S: If you are trying gdb's tui for the first time and your program is still laden with print statements, you can ungarble the screen after a printf output with Ctrl+L or the refresh command
  • PaulHoule
    Gawd, that image-based approach to programming has never been mainstream because it creates a terrible mess.Look at the nightmare notebooks you get from data scientists working in Python where they want to have their answers baked into a notebook that they can show to people and don't realize they need to separate code and data in version control and have a script you can run from top to bottom every single time if they want to put their skills on wheels.
  • airza
    i have learned a lot of interesting facts about haskell and lisp from this post. those facts make me want to run screaming away from trying to use either of them to develop software. My time with Haskell made me a better programmer and I bet that LLMs made some of the documentation more intelligible, but...
  • ux266478
    To be honest given the amount of structural obliteration you get out of GHC, image-based development sounds like a really bad idea. Haskell is such a weird and unintuitive language to understand from a systems perspective, because it's almost like you're restricted to writing macros for a language that you never directly see or interact with. The transformation from your source code to what the compiler spits out is can be highly non-local and unpredictable, even before you start introducing things like custom rewrite rules.To me, I think the smart way to work with Haskell is the exact opposite of iteration. Work it out on paper, refine it, find the algebraic rules for it, refine it some more, and then start writing code once you know exactly what you're doing. I think giving in to the temptation to Just Start Writing Code is how you end up with opaque type spaghetti. That's just my feelings on it.
  • inigyou
    A language server doesn't have to involve live reloading, and normally doesn't? I feel like these are two orthogonal concerns. A language server is used for things like autocomplete and error highlighting.I don't like them in principle because I believe the language should be more fully integrated with the IDE (like Eclipse does), but they do work, are a step up from syntax highlighting, and are practically a requirement if you have an NxM matrix of languages and IDEs.
  • antonvs
    > There’s no way to write Haskell that puts us inside the program process, so we will still need to restart in a debugger.If you’re regularly using a debugger while developing ordinary Haskell programs, you’re doing something terribly wrong. Possibly writing in a very imperative style?
  • kaveh808
    I have always viewed the Emacs/Slime/CL development environment as being a more frictionless approach than the compile/link/execute approach of most other languages, but I get the impression there are people who evangelize "image-based coding" without having tried it out themselves.The idea of not maintaining properly documented sources would terrify me.As people point out, if you are not careful and execute arbitrary code in the REPL, your source and image can drift out of sync. When I was working on [1], I would go days without relaunching my image, but all the development was done by evaluating code in Emacs buffers and seeing the results right away. Occasionally, things got convoluted enough that I relaunched the process as a sanity check.For me, the real benefit of iteratively modifying a live image lies in the sense of flow it engenders. I have not felt that sense in languages other than CL. I sometimes explain the feeling by saying than CL is the only language that I don't feel is fighting me.[1] https://github.com/kaveh808/kons-9
  • noobplus
    It is always cool to implement a powershell code in Linux style. Credits to the author of GHCup
  • UltraSane
    I find it so fascinating how many programmers proudly declare how they don't use any IDE when incredibly sophisticated tools like solidworks or Synopsis are universally used in engineering
  • refactor_master
    Sounds genuinely horrible to program this way.> A Lisp programmer does not need to …Have you even seen R? Jupyter notebooks? The above sounds like a level of insanity beyond that.The problem with checking things at runtime is that it’s an ever-moving target. Changed this? Now that other thing is out of sync. Changed that? Now the first thing is gone, and it came from far away so you can’t get it back in this session.
  • TacticalCoder
    > They don’t have to restart the program on exceptions, because the condition system allows resuming the crashing code from anywhere in the stack after the system has been patched with a fix.I'm "only" using Clojure (which some shall say is not a proper Lisp) and elisp (which is, well, elisp) but I catch every exceptions (including any yet uncaught ones) and I rarely need to restart the app. I've got an helper function to "restart" the app and I can pass a parameter: reset the state of the app or not (usually I don't and keep working with my current app state). As to the main process: I very rarely need to restart the JVM / get a new REPL.The whole thing is basically a very, very, very long REPL session.> A consequence of this way of working is that early in a Lisp project, there may not even be any source code to speak of. Instead, the evolving definition of the system exists only in the memory image of the running process and nowhere else.Yes but be careful... At times this shall bite you: you've got this function or this new definition of that function that you only had working in the REPL and which is not in source code yet. I typically have tests and I run them, from another process, totally unrelated to the one I'm developing in, that I regularly run (not just when I commit): this helps catch at least the most serious "desynch" issues (where the Lisp source code doesn't correspond anymore to what's in the REPL).> A Lisp programmer does not need to “switch over” to something else because they are already inside their program process. They never “compile and execute” the code because the code is already running and they edit it by hot-swapping code. They never restart in a debugger because they are already inside their program process and can inspect anything they want.Yup it's all really very sweet. But really: those are all part of that family of languages and not a kludge added later on to the language.Some people believe that because they have a console in the web dev tools in their browsers that can execute JavaScript code they've got the same thing as a Lisp. It's not anywhere near close to that.
  • forest_brothers
    [dead]