This is intended to be a brief report, so I'm not going to explain what Sweet Expressions are or why I am interested in them (although such an explanation, does, indeed, call for a "Curious Treehouse Musing") -- but in the process of trying to get this library up and running, I ran into a bug: it turns outh that Sweet Expressions cannot process a comment that comes right after a regular sexpr.
In the process of trying to wrap my head around the Sweet Expressions source code and figure out where and how comments are processed, I created a little macro to help me see how functions are called:
(defmacro debug-defun (fn-name fn-args &rest fn-body)
"Like defun but adds debugging info around the function definition."
(let* ((first-line (car fn-body)) ;; because the first line sometimes has to be the first
(has-declare (and
(listp first-line) (eq (car first-line) 'declare))) ;; declare check!
(body-bits (cdr fn-body))) ;; the remainder of the body
`(defun ,fn-name ,fn-args
,@(if has-declare `(,first-line)) ;; (declare) form? Put it here!
(if *debug*
(progn
(push " " *current-level*) ;; "increment" the level
(format t "~{~a~}IN FUN ~a~%" *current-level* ',fn-name))) ;; print out level/name of fn
(let
((function-result (multiple-value-list (progn ;; We need to capture the return value
,@(if (not has-declare) `(,first-line)) ;; Not declare form? first-line goes here!
,@body-bits)))) ;; put last of body here
(if *debug* (pop *current-level*)) ;; "decrement" the level -- we're done calling
(values-list function-result))))) ;; return the result!
This macro can easily be "deactivated", too, by commenting it out and uncommenting this macro:
(defmacro debug-defun (fn-name fn-args &rest body)
`(defun ,fn-name ,fn-args
;(format t "Hello, ~a~%" ',fn-name)
,@body))
But it turns out that this macro probably isn't as helpful as I thought it would be: I still struggle to see what value each symbol has, or what the algorithm is doing, at any one moment. It is the byproduct of how I am used to debugging code: with "print" statements! In my years of using PHP on web servers, Python on Amazon Web Services, and JavaScript, it's very easy (and sometimes necessary! because you don't have run-time access to an Amazon "Lambda" instance! among other scenarios) to use print statements or logs to show the states of variables.
However, in my previous internship, we were using Qt in a Windows application -- and while I probably could have used logs to get my bearings, and I sometimes even modified labels to confirm that I was looking at the right spot, it was more convenient to put in a breakpoint, attach to the running process, and step through the code. This, in turn, made me wonder how I can do that in Common Lisp -- and even accept that this might be the easiest option for debugging this issue.
Nonetheless, I appreciate creating that macro, even if I'm not going to use it. It was an interesting learning experience, helping me to better understand the power of Common Lisp macros and how to write them!
So, today, I'm going to try to do a "deep dive" into Common Lisp breakpoints and stepping. I also need to figure out how to run the Sweet Expression tests, or figure out my own way to do so -- and I need to create a test or two that would cause "Sweet Expressions" to choke, and then fix the issue.
Also, at the Experimental Airplane Association, this week is Virtual Ultralight Days! So I am going to try to catch a webinar or two on flying ultralights. (I have a special interest in aviation, and have a particular soft spot for ultralights, because my Grandpa built and flew one.)
Fun fact: For this post, I had to figure out how to insert code into Blogger; I found this blogpost and this help forum to be useful, although I had to figure out on my own that I needed to add the CSS into the blog's HTML, because the "Add CSS" option recommended in the instructions didn't exist...
No comments:
Post a Comment