laurent.orseau
2021-10-1 07:52:46

Seems canonical enough to me :slightly_smiling_face:


sorawee
2021-10-1 07:56:13

Turns out that this doesn’t work well. equal?-based hash is really too expensive and becomes the bottleneck of memoization for my code formatter. So I switched the data structure to a vector of hash instead.


markus.pfeiffer
2021-10-1 08:41:30

(match-define (hash-table ('key-a a) ('key-b b)) #hasheq( (key-a . "foo") (key-b . "bar"))


markus.pfeiffer
2021-10-1 08:41:34

of any use?


markus.pfeiffer
2021-10-1 08:42:11

oh, darn, didn’t read the question right


markus.pfeiffer
2021-10-1 08:43:00

disregard what I said


laurent.orseau
2021-10-1 10:27:33

@sorawee you can make your own hash functions


community
2021-10-1 12:11:32

@community has joined the channel


sorawee
2021-10-1 12:57:00

You mean using define-custom-hash-types? Tried that. The overhead is super high (even higher than the code in https://racket.slack.com/archives/C06V96CKX/p163306063508130)


laurent.orseau
2021-10-1 13:03:47

for some reason your link doesn’t work for me


laurent.orseau
2021-10-1 13:03:58

too bad it’s that slow though :confused:


sorawee
2021-10-1 13:04:41

My link is to the very first post of this thread — the one that asks the question


sorawee
2021-10-1 13:05:49

I guess that’s why it doesn’t work. It’s already “opened”


ryanc
2021-10-1 13:31:04

@sorawee How does the following perform? (define counter 0) (define (next-counter!) (begin0 counter (set! counter (add1 counter)))) (define ref (make-hasheq)) ;; K => Nat (define table (make-hasheqv)) ;; Nat => V (define (keys->nat k1 k2) (combine (hash-ref! ref k1 next-counter!) (hash-ref! ref k2 next-counter!))) (define (combine x y) ;; combines two Nats by (coarsely) interleaving bits (cond [(and (zero? x) (zero? y)) 0] [else (+ (bitwise-bit-field x 0 8) (arithmetic-shift (combine y (arithmetic-shift x -8)) 8))])) (define my-ref (case-lambda [(k1 k2) (hash-ref table (keys->nat k1 k2))] [(k1 k2 default) (hash-ref table (keys->nat k1 k2) default)])) (define (my-set! k1 k2 v) (hash-set! table (keys->nat k1 k2) v))


djholtby
2021-10-1 13:57:00

You can also do it with nested tables. (define table (make-hasheq)) (define ref (make-hasheq)) (define (my-ref x y) (define a (hash-ref! ref x gensym)) (define b (hash-ref! ref y gensym)) (hash-ref! (hash-ref! table a make-hasheq) b ...))


greg
2021-10-1 16:58:35

> I guess that’s why it doesn’t work. It’s already “opened” Thanks Slack for the example, how it can be hard to determine equality both efficiently and correctly? :stuck_out_tongue:


jbclements
2021-10-1 17:39:39

I think you mean “so this all changed long after the stepper was written” :wink: Thanks!


samth
2021-10-1 17:44:56

Well 15 years is all I can speak to, but my guess is that it has always worked that way


shu--hung
2021-10-1 20:23:26

I didn’t realize that the stepper was published in 2001 and it even predates Racket’s modern module system!!


shu--hung
2021-10-1 20:24:23

MzScheme :scream:

> 10. Flatt, M. PLT MzScheme: Language manual. Technical Report TR97–280, RiceUniversity, 1997.


shu--hung
2021-10-1 20:26:00

So the stepper introduces continuation marks into Racket? Wow!!


shu--hung
2021-10-1 20:31:02

> how it can be hard to determine equality both efficiently and correctly? Type theorists have been working on this problem for decades and it is still an ongoing work!


greg
2021-10-1 21:43:19

I’m afraid I watched too many episodes of Sesame Street to take this problem too seriously. https://www.youtube.com/watch?v=_Sgk-ZYxKxM


philip.mcgrath
2021-10-2 04:03:37

It’s worth noting that the identifier produced by (datum->syntax #f 'x) can be referenced or bound by any other identifier named x that has an empty set of scopes. In many cases syntax-local-introduce can be a better choice that datum->syntax for treating a bit of syntax as though it had been part of the input to the macro. In this case, though, the best choice would be using define-syntax-parameter and syntax-parameterize.