Arc Forumnew | comments | leaders | submitlogin
REPL variables
5 points by parenthesis 5926 days ago | 11 comments
fractal was asking about REPL variables ( http://arclanguage.org/item?id=776 ).

Here's a basic implementation. In ac.scm, change tl2 thus:

  (define (tl2)
    (display "arc> ")
    (on-err (lambda (c) 
              (set! last-condition* c)
              (display "Error: ")
              (write (exn-message c))
              (newline)
              (tl2))
      (lambda ()
        (let ((expr (read)))
          (if (eqv? expr ':a)
              'done
              (let ((val (arc-eval expr)))
                (arc-eval `(input-history-update ',expr)) ; added
                (arc-eval `(output-history-update ,val))  ; lines here
                (write (ac-denil val))
                (namespace-set-variable-value! '_that val)
                (namespace-set-variable-value! '_thatexpr expr)
                (newline)
                (tl2)))))))
And then put these in arc.arc :

  ; I couldn't find a pre-existing total macro-expander
  (def expand (expr)
    (if (acons expr)
        (macex (cons (car expr)
                     (map expand (cdr expr))))
        expr))

  (mac % () nil)
  (mac %% () nil)
  (mac %%% () nil)

  (def input-history-update (expr)
    (let expandedexpr (expand expr)
      (= %%% %%
         %% %)
      (mac % () expandedexpr)))

  (= ^ nil
     ^^ nil
     ^^^ nil)

  (def output-history-update (val)
    (= ^^^ ^^
       ^^ ^
       ^ val))
Then ^, ^^, ^^^ work like CL * , * * , * * * . And (%), (%%), (%%%) re-evaluate the last, second-last, third-last thing you typed in. (Obviously these are for if you haven't got readline.)


3 points by fractal 5926 days ago | link

Sweet, thanks for these! If only Arc was a lisp-2, we could continue the CL naming convention. I'd also like to point out these are useful even if you have readline:

  arc> (do-some-lengthy-computation)
    #<some value>
  arc> ;; D'oh! I wish I had assigned that somewhere!
vs

  CL> (do-some-lengthy-computation)
    #<some value>
  CL> (defvar tp *)
Or

  arc> (some (interesting (expression ...)))
    some-value
  arc> `(some (other (stuff ;; D'oh! I want to embed the
                            ;; previous expression here
vs

  CL> (some (interesting (expression ...)))
    some-value
  CL> `(some (other (stuff ,+)))

-----

2 points by parenthesis 5926 days ago | link

Spot the missing quote, should be

  (arc-eval `(output-history-update ',val))
not

  (arc-eval `(output-history-update ,val))

-----

1 point by sjs 5925 days ago | link

You should update the original post.

-----

2 points by parenthesis 5925 days ago | link

You're right, but being able to edit one's posts is time limited, and I was too late.

-----

2 points by kennytilton 5925 days ago | link

Coolio. Any way around seeing * redefining % each time?

-----

1 point by parenthesis 5925 days ago | link

Ah, yes, that's what I forgot to say: I also changed in arc.arc :

  (set safeset (annotate 'mac
                 (fn (var val)
                   `(do (if (bound ',var)
                            (if (~is ',var '%)
                                (do (disp "*** redefining ")
                                    (disp ',var)
                                    (writec #\newline))))
                        (set ,var ,val)))))

-----

1 point by sjs 5925 days ago | link

I changed it to:

    (tostring (mac % () expandedexpr))

-----

1 point by parenthesis 5925 days ago | link

Why does that work?

-----

2 points by sjs 5925 days ago | link

tostring captures whatever is sent to stdout.

    (tostring (prn "hi"))
returns the string "hi\n" instead of actually printing it.

-----

1 point by sjs 5925 days ago | link

So I guess that and thatexpr are obsoleted by this patch, no?

-----

3 points by parenthesis 5925 days ago | link

that and ^ do the same thing (but there's also ^^, ^^^).

thatexpr is like CL + .

But (%) is like (eval thatexpr), except % is a macro that gives you what the last thing entered expanded into. And so, since % is a macro, it itself is expanded away. Hence

  arc> 2
  2
  arc> (* ^ 2)
  4
  arc> (%) ; equivalent to entering (* ^ 2) again
  8
  arc> (%) ; and again
  16
  arc> (%) ; and again
  32
Whereas

  arc> 2
  2
  arc> (* ^ 2)
  4
  arc> (eval thatexpr) ; i.e. (eval (* ^ 2))
  8
  arc> (eval thatexpr) ; i.e. (eval (eval thatexpr)) i.e. (eval (eval (eval thatexpr))) etc.
  [infinite loop]

-----