1

I'm using quite a lot of (standard R6RS) hashtables in Chez Scheme, but it's not very nice working with them at the REPL because they are just printed as #<eq hashtable>. I have written a print-table function but it's a bit annoying to keep calling it every time I want to inspect my data.

It looks like Racket has a way to do custom printing for a given type. Is there any way to do something similar in Scheme?

tommaisey
  • 449
  • 2
  • 10
  • I'm now considering using association lists instead because they'll print nicer! Also in most cases I expect my tables to have fewer than ~50 elements, so perhaps performance won't be too much of a problem. – tommaisey Dec 20 '18 at 16:26
  • I imagine printing every key and value when evaluated to the hash table might not be practical always. – Sylwester Dec 20 '18 at 19:37
  • Yeah, maybe that's why it's not the default behaviour. Like I said, my maps will be quite small, so maybe association lists would be better. The possibility for relatively efficient immutability is quite attractive too. – tommaisey Dec 20 '18 at 23:31

1 Answers1

3

Chez Scheme does allow for custom reading and writing of most records, including hashtables. Chez Scheme provides a record-writer and record-reader procedure which allow customizing the functions used to write and read records:

http://cisco.github.io/ChezScheme/csug9.5/objects.html#./objects:s176

There are some good examples on that page, but an important detail is that you can specify #f as the writer, the default for new record types, which will use a format capable of being read back by the default reader. This won't work 100% of the time as there are some types which have no serializable representation, like functions.

Once I disable the special printer for eq-hashtables and the special printer for the base hashtables, I can see the default representation:

> (record-writer (record-rtd (make-eq-hashtable)) #f)
> (record-writer
    (record-type-parent
      (record-type-parent (record-rtd (make-eq-hashtable)))) #f)
> (make-eq-hashtable)
#[#{eq-ht icguu8mlhm1y7ywsairxck-0} eq #t #(0 1 2 3 4 5 6 7) 8 0 0]
> (define ht (make-eq-hashtable))
> (eq-hashtable-set! ht 'a "a")
> ht
#[#{eq-ht icguu8mlhm1y7ywsairxck-0} eq #t #(0 #<tlc> 2 3 4 5 6 7) 8 1 0]

Unfortunately, it looks like there's an object with a custom writer as part of the hashtable storage, so you can't use the default writer to see the entries.

gmw
  • 121
  • 2
  • Perfect, although not as convenient as I was hoping for, it looks like I might be able to do what I want with this. – tommaisey Dec 29 '18 at 17:56