Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hashtables don't accept empty list as key. #5

Closed
2bt opened this issue Oct 28, 2014 · 8 comments
Closed

Hashtables don't accept empty list as key. #5

2bt opened this issue Oct 28, 2014 · 8 comments

Comments

@2bt
Copy link

2bt commented Oct 28, 2014

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)
@leppie
Copy link
Member

leppie commented Oct 28, 2014

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

@leppie
Copy link
Member

leppie commented Oct 30, 2014

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.

@2bt
Copy link
Author

2bt commented Feb 16, 2015

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.

@leppie
Copy link
Member

leppie commented Feb 17, 2015

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))

@christoff-buerger
Copy link

I will think about it a bit more.

Will this be fixed or does...

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.

...outweigh R6RS conformance?

At the moment I use boilerplate code like above to create a special nil-record used in case of empty lists as keys. Its bothersome and fragile however, to maintain several product versions for different Scheme implementations.

@leppie
Copy link
Member

leppie commented Mar 8, 2016

I was thinking of building it into IronScheme libraries, but need to investigate. I think some hashtable procedure(s) are still done in C# which makes it tricky.

leppie added a commit that referenced this issue Mar 8, 2016
Update bootfile.
@leppie
Copy link
Member

leppie commented Mar 8, 2016

@christoff-buerger Should be fixed in last commit, let me know if you pick up issues.

@leppie leppie closed this as completed Mar 8, 2016
@christoff-buerger
Copy link

It works! Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants