💾 Archived View for thrig.me › tech › no-repl.gmi captured on 2024-08-18 at 18:33:53. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-04-19)

-=-=-=-=-=-=-

No Read-Eval-Print-Loop

Orthodoxy says to develop using a REPL, because REPL are good, and why wouldn't you develop without a REPL? Any language that lacks a REPL must obviously be inferior, right? This is some circular man-shaped straw.

I do not use REPL, much, besides the shell, which is mostly not for development, and IRC that also is not for development. Rarely will I experiment in a REPL

    $ eforth
    eFORTH v1984
     5414 10970
    2 base
     ok
    .s
     2 136 <sp
     ok
    !
     ok
    10
     ok
    .s
     10 <sp
     ok
    10 base !
     ok
    .s
     10 <sp
     ok
    $A base !
     ok
    .s
     2 <sp
     ok

but this is not a good development environment. For one, the input is rapidly scrolling to oblivion. There are no comments that explain to future me what is being tested or why something did or did not work. This input would need to be cleaned up and made presentable if there was an issue that needed to be shared. Line editing is absent (other REPL might be better at that). The information density is low. Usually there are far more typos and retries and copypasta, mercifully omitted here, that clutter up the history even more.

Usually I will very quickly give up on REPL and instead wrangle the text in a text file. This has various benefits, and no particular drawbacks.

Orthodoxy

I recommend running most of the examples in the REPL... this will help you get used to writing and understanding Lisp code, and it will help you retain everything you're learning.
-- Daniel Higginbotham, "Clojure for the Brave and True"

I fail to see how typing text into a REPL would be any more memorable than typing the same text into a text editor. The author then says that longer examples are best written into a file. Why not write them all to files, and manage those under version control? A counter-argument is that a REPL gives immediate feedback, but how fast does this need to be? I did not find the Clojure JVM to be very responsive compared to compiling and running small test C programs, and entr(1) can react to a file change, or one can execute a buffer in vi to accomplish much the same. Integrated Development Environments probably have a keyboard shortcut for "build and run and show me what it did".

If you had to, you could build a pretty reasonable programming environment out of just the REPL and any text editor that knows how to properly indent Lisp code.
-- Peter Seibel, "Practical Common Lisp"

This could be called a moderate orthodox view; the REPL is "for experimentation" but a text editor is available for when the REPL does not shine. My argument is that the REPL mostly does not shine; rlwrap can help make a bad REPL less bad, but adds complexity, and does not solve the lack of comments and lack of a save file under version control. Why not experiment in a file, using a text editor, and feed that over to a REPL, if need be?

REPL-Driven Development

Apparently some do most of their development in a REPL as opposed to REPL-based development where input from an editor somehow gets over to a REPL. Given how poor I find REPL to be compared to a text editor, I'm really not sure how REPL-driven development works. Maybe find someone who uses it to see how they make it work? REPL-based development I can do easily enough in vi using feed(1) to pipe code over to most any REPL. Or I can instead use entr(1) to run a whole file, which happens to work for music development (lilypond), writing documentation (TeX, ROFF), programming, etc, with files saved to version control.

Feed things to a REPL:

    $ grep feed ~/.exrc.lisp
    map \t :!feed % lisp
    $ grep feed ~/.exrc.fs
    map \e :!feed % eforth
    map \t :!feed % pforth
    map \y :!feed % gforth

Or one can write a wrapper around entr(1), here to build and preview ROFF:

    #!/bin/sh
    fname=$1 ; shift
    bname=`fdsplit root "$fname"`
    PATH=/usr/local/heirloom-doctools:$PATH ; export PATH
    aslines "$fname" "$@" |
    entr sh -c "make $bname.pdf && pkill -HUP mupdf"

and then run that with foo.roff as the argument and then hack away on foo.roff in whatever editor you want. Some REPL are instead pretty much constrained to one editor, and if you do not get along with emacs, and slime is not your thing, then too bad. With files I can use any editor I want, and feed(1) or entr(1) data however I want.

And how does version control work with REPL-driven development?

File Based Development

Remember the forgettable forth from a few pages ago? Compare that to a file:

10.txt

    #!/usr/bin/env perl
    #
    # 10 - add 10 to the stack in base 2, 8, 10, and 16

The language, and the purpose of the code, right up front. Some put a page of license and copyright spam here, so there is room do to files wrong.

    use 5.32.0;
    use warnings;
    use experimental 'signatures';
    use Carp 'croak';
    use Language::Eforth;
    our $f = Language::Eforth->new;

Boilerplate. This can often be reduced with macros or Import::Base.

    my $base = 10;
    for my $newbase (qw(2 8 10 16)) {
        my $enc = inbase( $newbase, $base );
        $f->eval("$enc base !\n10\n");
        $base = $newbase;
    }
    # back to base 10 - embed supports $hexnumber for
    # literal input, probably better than the inbase
    # conversion (but less educational)
    $f->eval( '$A base !' . " .s\n" );

    # this could also be done with an "alphabet", see
    # Number::AnyBase; ANS FORTH and Common LISP
    # however restrict the base to 2..36
    ...

Exactly where would all those comments go in a REPL? Or how does the RELP-driven development interact with version control?

https://thrig.me/src/Language-Eforth.git

A REPL (ksh) was useful to copy Language-Eforth/eg/10 to thrig.me/tech/10.txt, but that's mostly all I use REPL for.

Back to tech index

tags #lisp #forth