[plt-scheme] a tiny repl

From: Dave Herman (dherman at ccs.neu.edu)
Date: Sun Jun 28 22:23:28 EDT 2009

In my experience, the most clearly defensible uses of `eval' are when  
a program requires the full generality of evaluation of arbitrary  
Scheme code. Pretty much the only times I've needed it are when I  
write a DrScheme language (such as my JavaScript implementation) that  
compiles to PLT Scheme; when the programmer runs the code, the  
compiler generates Scheme which then needs to be evaluated.

Dave

On Jun 28, 2009, at 6:58 PM, Richard Cleis wrote:

> For what do you really need it?
>
> rac
>
>
> On Jun 28, 2009, at 4:43 PM, Ryan Culpepper wrote:
>
>> Hugh Myers wrote:
>>> On the off chance that others who read this list are as needy as
>>> myself, what follows is a tiny repl. I use an expanded version to  
>>> test
>>> and debug my current work--- single stepping through a chess game  
>>> for
>>> instance. Since I'm new to scheme, I've no knowledge of better  
>>> ways to
>>> do this, so feel free to criticize. It paid for itself by being
>>> helpful to me, gravy if helpful to someone else...
>>
>> I try to stay away from 'eval' unless I really need it. You could  
>> instead just keep a table of command names and the procedures that  
>> implement them. Here's how to do it:
>>
>> ;; repl : string -> (loops)
>> (define (repl prompt)
>>  (display prompt)
>>  (let* ([line (read-line)]
>>         [parts (regexp-split #px"\\s" line)])
>>    (when (pair? parts)
>>      (let* ([command-part (car parts)]
>>             [parameter-parts (cdr parts)]
>>             [command (lookup-command command-part)]
>>             [parameters (for/list ([part parameter-parts])
>>                           (string->actual part))])
>>        (when command
>>          (apply command parameters))))
>>    (repl prompt)))
>>
>> ;; lookup-command : string -> procedure/#f
>> ;; Gets the procedure that implements the given command,
>> ;; or #f if given an unknown command name.
>> (define (lookup-command command-name)
>>  ;; commands : (listof (cons string procedure))
>>  ;; You can lift this to top-level, but you must put it *after*
>>  ;; the definitions of 'repl-help', 'jmp', and 'print-board'.
>>  (define commands
>>    (list (cons "h" repl-help)
>>          (cons "q" (lambda () (escape 'Bye!)))
>>          (cons "j" jmp)
>>          (cons "p" print-board)))
>>  (let ([entry (assoc command-name commands)])
>>    (and entry (cdr entry))))
>>
>> A few of your functions can now go away, and the rest are unchanged:
>>
>> (define (repl-help)
>>  (printf "~a~%" "Commands are h,p, and q.")
>>  (printf "~a~%" "Where:")
>>  (printf "~a~%" "       h =s 'help'")
>>  (printf "~a~%" "       j n =s 'jmp n plys'")
>>  (printf "~a~%" "       p =s 'print-board'")
>>  (printf "~a~%" "       q =s 'quit'"))
>>
>> (define (jmp n)
>>  (printf "jump forward ~A ply in movelist~%" n))
>>
>> (define (print-board)
>>  (printf "display board~%"))
>>
>> (define (escape v)
>>  (abort-current-continuation
>>   (default-continuation-prompt-tag)
>>   (lambda () v)))
>>
>> (define (string->actual s)
>>  (let ([value (if (string->number s)
>>                   (string->number s)
>>                   (string->symbol s))])
>>    value))
>>
>> (define (test-repl)
>>  (repl "test> "))
>>
>> Ryan
>> _________________________________________________
>> For list-related administrative tasks:
>> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.