[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
read-hash-extend and geiser
From: |
Panicz Maciej Godek |
Subject: |
read-hash-extend and geiser |
Date: |
Tue, 11 Sep 2012 23:18:23 +0200 |
Hey,
I've been fighting to make vectors, hash tables and objects
usable from scheme level. I therefore came up with a common
interfacing method to those objects:
(define (getter obj key)
(cond ((vector? obj)
(vector-ref obj key))
((hash-table? obj)
(hash-ref obj key))
((instance? obj)
(slot-ref obj key))))
(define (setter obj key value)
(cond ((vector? obj)
(vector-set! obj key value))
((hash-table? obj)
(hash-set! obj key value))
((instance? obj)
(slot-set! obj key value))))
(define ref (make-procedure-with-setter getter setter))
so that instead of (vector-ref v 0) one can now write (ref v 0).
This is still lame, though, so I decided to make use of the
infamous read-hash-extend, to write #[v 0] instead.
I quickly wrote a function to support the new syntax, with
no error detection, namely:
(read-hash-extend #\[
(lambda (char port)
(let* ((exp `(ref ,(read port) ,(read port))))
(catch 'read-error (lambda()(read port))
(lambda(key . args) key))
exp)))
To my surprise, I was able to evaluate the code containing
this new syntax in emacs/geiser
(define v #(1 2 3))
#[v 0] ;C-xC-e => 1
(set! #[v 0] 20)
v ; => #(20 2 3)
My conscience, however, was deeply dissatisfied with this code,
so I wrote a more decent equivalent:
(read-hash-extend #\[
(let ((process (match-lambda
((object key)
`(ref ,object ,key))
(default
default))))
(lambda (char port)
(let loop ((exp '()))
(let ((char (peek-char port)))
(cond ((char-whitespace? char)
(read-char port)
(loop exp))
((eq? char #\])
(process (reverse exp)))
(#t
(loop (cons (read port) exp)))))))))
To my bigger surprise, this code could not be evaluated in emacs/geiser
in a traditional way, but when invoked using eval and wrapped in string, like
(primitive-eval (with-input-from-string "#[v #[v 0]]" read))
it worked just as expected.
Does anyone of you know what could be the source of the
difference?
BTW I don't know how legitimate it is to use the read-hash-extend modification.
I remember that guile 1.4 had an infixed module, but I see that it is no longer
shipped with the package. Could anyone tell, why?
Best regards,
M.
- read-hash-extend and geiser,
Panicz Maciej Godek <=