unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: Jan Nieuwenhuizen <janneke@gnu.org>
Cc: guile-user@gnu.org
Subject: Re: cannot compile: srfi-10 define-reader-ctor 'hash '#,(
Date: Sat, 05 Jul 2014 15:40:47 +0200	[thread overview]
Message-ID: <874myvudnk.fsf@gnu.org> (raw)
In-Reply-To: <87y4w9jog8.fsf@drakenvlieg.flower> (Jan Nieuwenhuizen's message of "Fri, 04 Jul 2014 14:30:47 +0200")

Jan Nieuwenhuizen <janneke@gnu.org> skribis:

> (use-modules (srfi srfi-10))
>
> (define-reader-ctor 'hash
>        (lambda elems
>          (let ((table (make-hash-table)))
>            (for-each (lambda (elem)
>                        (apply hash-set! table elem))
>                      elems)
>            table)))

In this example, you want the reader extension to be available at
compile time, and not necessarily at run time.  However, by writing the
code as is, the reader extension is available only at run time, hence
the error.

To require evaluation of the ‘define-reader-ctor’ form at compile time,
change the code to (info "(guile) Eval When"):

--8<---------------cut here---------------start------------->8---
(eval-when (expand)
  (define-reader-ctor 'hash
    (lambda elems
      (let ((table (make-hash-table)))
        (for-each (lambda (elem)
                    (apply hash-set! table elem))
                  elems)
        table))))
--8<---------------cut here---------------end--------------->8---

Now, you’ll get this error:

--8<---------------cut here---------------start------------->8---
$ guile ~/tmp/hash.scm
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;       or pass the --no-auto-compile argument to disable.
;;; compiling /home/ludo/tmp/hash.scm
;;; WARNING: compilation of /home/ludo/tmp/hash.scm failed:
;;; ERROR: build-constant-store: unrecognized object #<hash-table 187ecc0 3/31>
cat
--8<---------------cut here---------------end--------------->8---

The problem here is that the reader extension above returns (at compile
time) a hash table.  However, a hash table as such cannot appear in
source code text, hence the error.

Instead, you’d want the reader extension to return source code that
constructs the hash table.  First, a macro:

--8<---------------cut here---------------start------------->8---
(define-syntax build-hash-table
  (syntax-rules ()
    ((_ table (key value) rest ...)
     (begin
       (hash-set! table key value)
       (build-hash-table table rest ...)))
    ((_ table)
     table)))

(define-syntax-rule (hash-table (key value) ...)
  (let ((table (make-hash-table)))
    (build-hash-table table (key value) ...)))
--8<---------------cut here---------------end--------------->8---

With that macro, we get:

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,expand (hash-table ("a" 1) ("b" 2) ("c" 3))
$2 = (let ((table (make-hash-table)))
  (hash-set! table "a" 1)
  (begin
    (hash-set! table "b" 2)
    (begin (hash-set! table "c" 3) table)))
--8<---------------cut here---------------end--------------->8---

Now, if in addition you want #, syntax for that, you can write:

--8<---------------cut here---------------start------------->8---
(eval-when (expand)
  (define-reader-ctor 'hash
    (lambda elems
      `(hash-table ,@elems))))

(define (animal->family animal)
  (hash-ref #,(hash ("tiger" "cat")
                    ("lion"  "cat")
                    ("wolf"  "dog"))
            animal))

(display (animal->family "lion"))
(newline)
--8<---------------cut here---------------end--------------->8---

But I’m not sure the #, extension is worthwhile here.

HTH,
Ludo’.



       reply	other threads:[~2014-07-05 13:40 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87y4w9jog8.fsf@drakenvlieg.flower>
2014-07-05 13:40 ` Ludovic Courtès [this message]
2014-07-31  6:27   ` cannot compile: srfi-10 define-reader-ctor 'hash '#,( Jan Nieuwenhuizen
2014-07-31 19:15     ` Neil Jerram
2014-08-14 10:27       ` Taylan Ulrich Bayirli/Kammer
2014-08-14 19:42         ` Neil Jerram
2014-08-14 19:54           ` Taylan Ulrich Bayirli/Kammer
2014-08-17 15:08       ` Ludovic Courtès
2014-08-11 15:48     ` Ludovic Courtès
2014-08-13 19:59       ` Jan Nieuwenhuizen
2014-08-13 20:43         ` Marko Rauhamaa
2014-08-13 21:00           ` Jan Nieuwenhuizen
2014-08-13 21:13             ` Ludovic Courtès
2014-08-13 21:33             ` Marko Rauhamaa
2014-08-14  4:03             ` Mark H Weaver
2014-08-13 21:06         ` Ludovic Courtès
2014-08-14  9:19         ` Panicz Maciej Godek
2014-08-14  9:53           ` Marko Rauhamaa
2014-08-14 10:30             ` Panicz Maciej Godek
2014-08-14 10:36               ` Marko Rauhamaa
2014-08-14 10:45                 ` Panicz Maciej Godek
2014-08-14 12:59                   ` Marko Rauhamaa
2014-08-14 13:58                     ` Panicz Maciej Godek
2014-08-14 11:13                 ` Taylan Ulrich Bayirli/Kammer
2014-08-14 13:17                   ` Marko Rauhamaa
2014-08-14 14:34                     ` Taylan Ulrich Bayirli/Kammer
2014-08-14 17:16                       ` Marko Rauhamaa
2014-08-14 18:28                         ` Taylan Ulrich Bayirli/Kammer
2014-08-14 19:24                           ` Marko Rauhamaa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874myvudnk.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=guile-user@gnu.org \
    --cc=janneke@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).