One could use an expression like "~" to mark the expressions that one would like to trace when evaluated.
e.g.:
would only print the result of the hidden "list" calls (quasiquote expands to
I really think this would be better than the commonly-used solutions out there. Other tracing solutions:
* tracing functions: usually nice, except sometimes you only want to see the result of a particular call in the code, not all calls. Also, I sometimes wish I could define the condition on which the trace is shown... i.e. a test of the arguments.
* breakpoints: sometimes you don't want to trace, not break!
* copying expressions: awkward, non-modular, messy (need to be deleted later).
* assigning the value to a variable, printing it later: one can always substitute
e.g.:
(defun analyze (group)
(let* ((games (get-pairs group))
(scores (mapcar #'(lambda (game)
(progn (format t "~A:" game)
`(,game ,(read))~ )) ;; <--- THE ~ IS HERE!
games))
(table (make-table group scores)))
(format t "~A~%" scores)))would only print the result of the hidden "list" calls (quasiquote expands to
(list game (read))).I really think this would be better than the commonly-used solutions out there. Other tracing solutions:
* tracing functions: usually nice, except sometimes you only want to see the result of a particular call in the code, not all calls. Also, I sometimes wish I could define the condition on which the trace is shown... i.e. a test of the arguments.
* breakpoints: sometimes you don't want to trace, not break!
* copying expressions: awkward, non-modular, messy (need to be deleted later).
* assigning the value to a variable, printing it later: one can always substitute
EXPR with (let ((temp EXPR)) (format t "~A~%" temp) temp). Maybe the ~ could be interpreted as a macro expanding to this.
(no subject)
Date: 2006-06-17 06:40 pm (UTC)It would be pretty easy to define a TRACE-IF used like (trace-if 'function-name (lambda (arg1 arg2) (some-condition arg1))).
(no subject)
Date: 2006-06-17 06:50 pm (UTC)Thanks!
<< or make the ~ a read macro and place it before instead of after (which is more readable anyway, I think). >>
Is your suggestion this:
?
If so, this has two problems.
(1) it sucks to have to write the extra parentheses, as in
(2) As you can see, the print is printing the expression raw, whereas we want to see it evaluated.
(no subject)
Date: 2006-06-17 06:55 pm (UTC)Use set-macro-character instead of defmacro, and have that expand it into something like (report 'expr expr) where you define REPORT as a function that displays the subject expression and the evaluated result in some nice way you like.
(no subject)
Date: 2006-06-17 07:25 pm (UTC)Nice. This solves the extra parentheses problem! Now I just to figure out how to evaluate that stuff. Just doing
evalwon't work.I take that back - eval does work
Date: 2006-06-17 07:41 pm (UTC)side-effects are a problem!
Date: 2006-06-17 08:55 pm (UTC)problem solved!
Date: 2006-06-17 10:42 pm (UTC)but I don't understand why this solution only evals once while the let-solution evals twice.
oops, still problematic!
Date: 2006-06-17 11:21 pm (UTC)printshould after the eval in the read-eval-print loop!Re: oops, still problematic!
Date: 2006-06-18 02:51 am (UTC)Re: oops, still problematic!
Date: 2006-06-18 04:24 am (UTC)(defun tilde-reader (stream char) (let ((e (read stream))) `(rep ',e ,e))) (defun rep (expr result) (format t "~A => ~A~%" expr result) result) (set-macro-character #\~ #'tilde-reader)I find it weird that tilde-reader returns a function call!
In other words, that set-macro-character takes a function returning a function call. But then again, isn't this how all macros are done?
Re: oops, still problematic!
Date: 2006-06-18 08:02 am (UTC)