(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 (+ (py-hash 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

)) (aif it (ref x '__hash__) (it) (hash x complexity)))