* read-hash-extend and geiser
@ 2012-09-11 21:18 Panicz Maciej Godek
2012-09-12 1:57 ` Panicz Maciej Godek
0 siblings, 1 reply; 2+ messages in thread
From: Panicz Maciej Godek @ 2012-09-11 21:18 UTC (permalink / raw)
To: guile-user
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.
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: read-hash-extend and geiser
2012-09-11 21:18 read-hash-extend and geiser Panicz Maciej Godek
@ 2012-09-12 1:57 ` Panicz Maciej Godek
0 siblings, 0 replies; 2+ messages in thread
From: Panicz Maciej Godek @ 2012-09-12 1:57 UTC (permalink / raw)
To: guile-user
OK, I think I've found the reason:
the ']' was not removed from the port,
so it caused a read error
> (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 #\])
(read-char port)
> (process (reverse exp)))
> (#t
> (loop (cons (read port) exp)))))))))
The question regarding the infix module still remains, though ;]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-09-12 1:57 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-11 21:18 read-hash-extend and geiser Panicz Maciej Godek
2012-09-12 1:57 ` Panicz Maciej Godek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).