Re: SETF for functions returning multiple values.
"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]> Tue, 9 Jun 2026 03:43:40 -0700
| Newsgroups | gmane.lisp.lispworks.general |
|---|---|
| Message-ID | <[email protected]> |
The only hitch that I ran into, when making all digits and + and -, into non-terminating macro characters in the readtable - is that when printing out items, the PRINT-OBJECT apparently uses the *READTABLE* to discern when it should insert an escape backslash ahead of every character.
So I grab a plain vanilla copy of a readtable and keep it around for thwarting this ugly result. With an around method (PRINT-OBJECT :AROUND (SYMBOL T)) I do:
————————————————
(defvar *vanilla-readtable* (copy-readtable nil))
(defmacro with-vanilla-readtable (&body body)
`(let ((*readtable* *vanilla-readtable*))
,@body))
(let (#+:LISPWORKS (lw:*handle-warn-on-redefinition* nil))
;; Prevent printouts from using xxx\-\1\2\3 for xxx-123, etc. ; <- make the digit magic invisible ;-)
(defmethod print-object :around ((object symbol) out-stream)
(with-vanilla-readtable
(call-next-method))))
—————————————————————
Then, just for safety purposes, I ensure that any attempt to modify the *READTABLE* is prevented if it is the vanilla readtable…
———————————————————
(defun report-attempt-to-write-vanilla-readtable (rt)
(when (eq rt *vanilla-readtable*)
(error "Vanilla Readtable is Read-Only!")))
#+:LISPWORKS
(progn
(lw:defadvice (set-dispatch-macro-character not-in-vanilla-readtable :before)
(disp-char sub-char function &optional (readtable *readtable*))
(declare (ignore disp-char sub-char function))
(report-attempt-to-write-vanilla-readtable readtable))
(lw:defadvice (set-macro-character not-in-vanilla-readtable :before)
(char function &optional non-terminating-p (readtable *readtable*))
(declare (ignore char function non-terminating-p))
(report-attempt-to-write-vanilla-readtable readtable)))
—————————————————
There is a similar pair of advice for SBCL.
With these patches in place I have not run into any problems from my extended number syntax.
- DM
> On Jun 9, 2026, at 03:17, Madhu (as enometh at meer dot net) <[email protected]> wrote:
>
> * "David McClain (as dbm at refined-audiometrics dot com)" <[email protected]> :
> Wrote on Mon, 8 Jun 2026 11:13:44 -0700:
>> I made my own digits become macro characters so that I can directly
>> handle numbers written like these:
>> +1°23’.23
>> 2026/06/08T11:10:09U+7
>> 520-234-3474
>> and of course any number can be written with embedded comma or
>> underscore: 1_234.5192_5542_112D0
>
> Thanks, (I remember this as something I couldn't solve decades ago
> when I tried to use the reader)
>
> (comment to tfb below)
>
>> I love it! Lisp no longer feels like a straightjacket to me. I can
>> just directly type in the numbers as I need them.
>>
>> The only other time in my life where I had such freedom was in my
>> ancient Forth Mount Control Systems on the world’s largest telescopes.
>>
>>> On Jun 8, 2026, at 11:02, Tim Bradshaw (as tfb at tfeb dot org)
>>> <[email protected]> wrote:
>
>>> (setf (values p1 p2) <form-returning-two-values>) should work when
>>> p1 and p2 are places (the spec talks about this).
>
>>> If F is a function returning two values, then you can't write a
>>> (SETF F) function for it, but you can write a setf expansion pretty
>>> easily. So then you just can say (setf (f ...) (values v1 v2)).
>>>
>>> I don't think I've seen this done elsewhere. Does it strike people
>>> as reasonable?
>>>
>>> The reason I'm asking is that the delimited-string reading thing
>>> I've been cleaning up now lets you control the closing delimiter, so
>>> that for instance #D[foo/bar.ldat] might read as the contents of the
>>> file foo/bar.ldat (ie the opening and closing delimiters are
>>> different now, which they used not to be.
>>>
>>> The function which lets you set up handlers is get-dsr-handler and
>>> it now returns two values the handler (or NIL) and the closing
>>> delimiter (or NIL if it's the same as the opening delimiter).
>>>
>>> So I want to be able to say (setf (get-dsr-handler #\[) (values
>>> my-handler #\])) say.
>
> I'd just use a cons. My cmucl-init has a read-verbatim-string reader
> with this comment
>
> ```
> (defvar *matching-delim-pairs* '((#\( . #\)) (#\{ . #\}) (#\[ . #\]))
> "Alist of (LDELIM . RDELIM) characters, for delimiting strings read by
> VERBATIM-STRING-READER."))
>
> (setf (documentation 'verbatim-string-reader 'function) #$<reads
> $#X...X, where "..." is read verbatim. X, the first character read is
> treated as the delimiter. If *USE-MATCHING-DELIM-PAIRS-P* is non-NIL
> (default), look in the alist *MATCHING-DELIM-PAIRS* to find a matching
> delimiter, which is then used to terminate reading the string<))
> ```
>
> (I think I had to set the documentation string in a separate form
> because of I couldn't evaluate the (defun ...) form in emacs -- in
> certain lisps -- if i put it inside the function)
>
>
>>> [The actual hidden motivation for this is an utterly perverse usage
>>> I thought of: you can make any digit character be an opening
>>> delimiter and the closing delimiter for all of them be #\., and with
>>> a suitable handler function
>>>
>>> ? #D1213,456,789.
>>> 1213456789
>>>
>>> And even
>>>
>>>> #16DFFFF FF00 ABCD.
>>> 281474959977421
>>>
>>> So that's pretty neat.]
>
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> [email protected]
> http://www.lispworks.com/support/lisp-hug.html