2019년 1월 8일 화요일

[on lisp] 4.6 I/O 입출력

4.6 I/O
Figure 4.7은 I/O 유틸리티의 세 가지 예를 보여준다.
이러한 유틸리티의 필요성은 프로그램마다 다르다.
;; Figure 4.7: I/O functions.
(defun readlist (&rest args)
  (values (read-from-string
       (concatenate 'string "(" 
                         (apply #'read-line args)
                      ")"))))

(defun prompt (&rest args)
  (apply #'format *query-io* args)
  (read *query-io*))     

(defun break-loop (fn quit &rest args)
  (format *query-io* "Entering break-loop.~%")
  (loop
    (let ((in (apply #'prompt args)))
      (if (funcall quit in)
       (return)
          (format *query-io* "~A~%" (funcall fn in))))))
여기 4.7은 대표적인 샘플일 뿐이다. 첫 번째는 사용자가 괄호없이 표현식을 입력 할 수 있게 하려는 경우다.
입력 행(a line of input)을 읽고 그것을 리스트로 리턴한다.

>(readlist)
Call me "Ed"
(CALL ME "Ed")
값을 호출하면 하나의 값만 반환.

prompt 함수는 질문, 읽기, 대답을 결합한다.
> (prompt "Enter a number between ~A and ~A.~%>> " 1 10)
Enter a number between 1 and 10.
>> 3
3

마지막으로 break-loop는 리습의 toplevel(REPL같은거)을 모방한 것이다.
두 개의 함수과 &rest 인수를 취하여, 프롬프트에 반복적으로 제공된다.
두 번째 함수가 입력에 대해 false를 반환하면 첫 번째 함수가 입력에 적용된다.
> (break-loop #'eval #'(lambda (x) (eq x :q)) ">> ")
Entering break-loop.
>> (+ 2 3)
5
>> :q
:Q
이것이 커먼리습 벤더들이 일반적으로 런타임 라이센스를 주장하는 이유이다.
만약 eval을 런타임에 실행할 수 있는 경우, 어떤 Lisp프로그램에도 Lisp가 포함될 수 있다.
(If you can call eval at runtime, then any Lisp program can include Lisp.)

댓글 없음:

댓글 쓰기