(define-module (language python hash) #:use-module (oop goops) #:use-module (oop pf-objects) #:export (py-hash complexity xy pyhash-N)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define N #xefffffffffffffff) (define pyhash-N N) (define-inlinable (xy v seed) (modulo (logxor seed (+ v #x9e3779b9 (ash seed 6) (ash seed -2))) N)) (define complexity 10) ;; The default is to use guile's hash function (define-method (py-hash x) (hash x N)) (define-method (py-hash (x )) (define i 0) (let lp ((x x)) (if (< i complexity) (begin (set! i (+ i 1)) (if (pair? x) (xy (lp (car x)) (lp (cdr x))) (py-hash x))) 0))) (define-method (py-hash (x )) (let ((n (min complexity (vector-length x)))) (let lp ((i 0) (s 0)) (if (< i n) (lp (+ i 1) (xy (py-hash (vector-ref x i)) s)) s)))) (define-method (py-hash (x

)) (define (next) (catch #t (lambda () (next-method)) (lambda x (hash x N)))) (aif it (ref-class x '__hash__ #f) (it) (next)))