Hashtables don't accept empty list as key.
Created by: 2bt
To my understanding this programme conforms with r6rs and it runs without problems in racket. IronScheme throws an exception.
(import (rnrs))
(hashtable-ref (make-eq-hashtable) '() 'default)
Imported comments:
By leppie on 2014-10-28 12:04:33 UTC
Hmmm, this is interesting. An empty list is a null
and it is exactly that in IronScheme/CLR. I will see what I can do :)
Thanks
By leppie on 2014-10-30 06:16:42 UTC
Unfortunately, this is a limitation with the .NET implementation of hashtables...
I could work around it, by creating some substitute for null but it seems hacky, and then you have differences in behavior between .NET and IronScheme which I try my best to avoid.
I will think about it a bit more.
By 2bt on 2015-02-16 14:08:07 UTC
In the meantime, I've been doing something like this:
(define-record-type nil-record (sealed #t) (opaque #t))
(define nil (make-nil-record))
(define hashtable-ref*
(lambda (h k d)
(hashtable-ref h (if (null? k) nil k) d)))
(define hashtable-set!*
(lambda (h k v)
(hashtable-set! h (if (null? k) nil k) v)))
(define hashtable-delete!*
(lambda (h k)
(hashtable-delete! h (if (null? k) nil k))))
(define hashtable-contains?*
(lambda (h k)
(hashtable-contains? h (if (null? k) nil k))))
(define hashtable-entries*
(lambda (h)
(let-values
(((kv vv) (hashtable-entries h)))
(let ((n (vector-length kv)))
(do ([i 0 (+ i 1)])
((= i n))
(when (eq? (vector-ref kv i) nil) (vector-set! kv i '()))))
(values kv vv)))))
You're right. It feels very hacky and I'm not happy with it. But I need this behaviour of a project. Do you maybe have a better idea? Great work, btw.
By leppie on 2015-02-17 11:03:16 UTC
That's about right.
You could probably use vector-map
instead of the do
in the last proc.
If you really want to you can use macros to clean it up, but IMO it is too much effort in this case.
Eg:
(define-syntax-rule (null/subst k) (if (null? k) nil k))