bel icon indicating copy to clipboard operation
bel copied to clipboard

Implement a `prompt` (environment) function

Open masak opened this issue 5 years ago • 2 comments

Environment as in #109. The direct purpose would be to have the Bel REPL be a program, and (in Bel tradition) be a small program. Something like this:

(def repl ()
  (awhen (read (prompt "> "))
    (print:bel it)
    (repl)))

Not sure it can be made quite that short, but it's an ideal to strive towards.

I also realized that a really good prompt would listen to keystrokes, not just characters from ins. In other words, it would listen to essentially another API (or at least not exclusively the ins character stream), in order to

  • Move the cursor around on the input line
  • Move through history (up and down)

and no doubt many more functions of essentially rlwrap.

(Hm, another issue with the example code above: I want it to abort on EOF/^D and the like, but not on empty string.)

masak avatar Jul 14 '20 12:07 masak

(Hm, another issue with the example code above: I want it to abort on EOF/^D and the like, but not on empty string.)

Heh; it's even trickier than that; I'd probably not want to print anything (except a new prompt) in case the input was completely empty (save for whitespace). So that should probably figure into the code; three cases (quit, no output, eval/output).

masak avatar Jul 14 '20 12:07 masak

I really liked the simplicity of the "central logic for a Lisp metacircular evaluator" described in the Kernel thesis:

($define! interpreter
   ($lambda () (rep-loop (make-initial-env))))

($define! rep-loop
   ($lambda (env)
      (display ">>> ")
      (write (mceval (read) env))
      (newline)
      (rep-loop env)))

($define! mceval
   ($lambda (expr env)
      ($cond ((symbol? expr) (lookup expr env))
      ((pair? expr) (mceval-combination expr env))
      (#t expr))))

Something like that simplicity is what I'm striving for here. The rep-loop is similar to the repl I defined above; in fact it skips the EOF check. If I did that, I would have:

(def repl ()
  (print:bel:read:prompt "> ")
  (repl))

Or maybe

(def repl ()
  (while t
    (print:bel:read:prompt "> ")))

Depending on whether one prefers tail recursion, or iteration.

masak avatar Nov 18 '20 03:11 masak