Paraprogramming Dispatches


EURISKO lives


Lisp
Eugene Zaikonnikov

When I wrote about EURISKO a few years before there hardly was an expectation of a follow-up. The system was a dusty legend with some cynical minds arguing whether it existed in the first place.

However, Lenat’s death in August last year has unlocked his SAILDART archives account. This has led to a thrilling discovery of both AM and EURISKO sources by WhiteFlame. In a further development, seveno4 has managed to adapt EURISKO to run on Medley Interlisp.

While I marveled at the idea of discovery systems before I hadn’t even considered ever running EURISKO myself as a possibility. Truly an Indiana Jones finding the Lost Ark moment. Yet this very low probability event has indeed happened, as documented in the video below. Rewind to 8:20 for the Medley run.

Deannoyifying SLIME


Lisp
Eugene Zaikonnikov

Over all these years I don’t think I ever wanted to close all existing SLIME connections when attaching to a remote host. Similarly, the version mismatch between SWANK and SLIME frontend has never stopped me following through with connection. I did however fumbled with y/n confirmations plenty of times. The snippet below removes these interactive checks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(defun slime-check-version (version conn)
  (or (equal version slime-protocol-version)
      (equal slime-protocol-version 'ignore)
      (message
       (format "Versions differ: %s (slime) vs. %s (swank)."
               slime-protocol-version version))
      (slime-net-close conn)
      (top-level)))

(defun slime-connect (host port &optional _coding-system interactive-p &rest parameters)
  "Connect to a running Swank server. Return the connection."
  (interactive (list (read-from-minibuffer
                      "Host: " (cl-first slime-connect-host-history)
                      nil nil '(slime-connect-host-history . 1))
                     (string-to-number
                      (read-from-minibuffer
                       "Port: " (cl-first slime-connect-port-history)
                       nil nil '(slime-connect-port-history . 1)))
                     nil t))
  (slime-setup)
  (message "Connecting to Swank on port %S.." port)
  (slime-setup-connection (apply 'slime-net-connect host port parameters)))

A useful feature for working on *nix backends is an ability to parse integers as epoch time in SLIME inspector. For this we need to minimally extend emacs-inspect found in swank-fancy-inspector.lisp:

1
2
3
4
5
6
7
8
9
10
11
12
13
(defmethod emacs-inspect ((i integer))
  (append
   `(,(format nil "Value: ~D = #x~8,'0X = #o~O = #b~,,' ,8:B~@[ = ~E~]"
	      i i i i (ignore-errors (coerce i 'float)))
     (:newline))
   (when (< -1 i char-code-limit)
     (label-value-line "Code-char" (code-char i)))
   (label-value-line "Integer-length" (integer-length i))
   (ignore-errors
     (label-value-line "Universal-time" (format-iso8601-time i t)))
   (ignore-errors
     (label-value-line "Epoch-time"
		       (format-iso8601-time (+ i 2208988800) t)))))

Tweaking SLIME Xref for Remote Images


Lisp
Eugene Zaikonnikov

By the nature of embedded development one spends a lot of time debugging on target devices. SLIME experience for the most part is as smooth as on local host with the exception of cross referencing. Swank backend on target is reporting local paths in xref records which the frontend on your host then tries to open.

The canonical workaround from the user manual is using slime-tramp contrib, allowing you to navigate the source tree on remote target over SSH. I however greatly prefer to work on the local copy of the source code, with much lower latency (SSH over VPN over cellular to a remote site is no fun) and ability to stage and commit changes immediately. A somehwat kludgy workflow that does the trick is using a hacked slime-postprocess-xref below to substitute $HOME in xref records. The source tree in remote home has to be placed in the same relative location as on your host. One should also remember copying their local tree to remote at the end of debugging session, in case the instance has to be restarted.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
;;; A modified version that substitutes HOME in remote images with local ones
;;; enabling local code navigation with the usual SLIME xref tools
(defun slime-postprocess-xref (original-xref)
  "Process (for normalization purposes) an Xref comming directly
from SWANK before the rest of Slime sees it. In particular,
convert ETAGS based xrefs to actual file+position based
locations."
  (if (not (slime-xref-has-location-p original-xref))
      (list original-xref)
    (let ((loc (slime-xref.location original-xref)))
      (slime-dcase (slime-location.buffer loc)
        ((:etags-file tags-file)
         (slime-dcase (slime-location.position loc)
           ((:tag &rest tags)
            (visit-tags-table tags-file)
            (mapcar (lambda (xref)
                      (let ((old-dspec (slime-xref.dspec original-xref))
                            (new-dspec (slime-xref.dspec xref)))
                        (setf (slime-xref.dspec xref)
                              (format "%s: %s" old-dspec new-dspec))
                        xref))
                    (cl-mapcan #'slime-etags-definitions tags)))))
        (t
         ;; Find the /home/someuser/ path component and replace it
         ;; with our local $HOME, if any
         (setf (cadr (slime-location.buffer loc))
               (replace-regexp-in-string "^/[^/]+/[^/]+"
                                         (getenv "HOME")
                                         (cadr (slime-location.buffer loc))))
         (list original-xref))))))

Announcing deptree


Lisp
Eugene Zaikonnikov

Deptree is a tool to list and archive dependency snapshots of (ASDF-defined) projects. We at Norphonic use it in the product build pipeline, but it can be useful for integration workflows as well. The task sounds common enough so there’s little doubt am reinventing the wheel with this. Alas, I couldn’t find any readily available solutions nor good folks at #commonlisp could recall of any, so there.

Available in the latest Quicklisp.

« Older Posts Newer Posts »