unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* 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).