     dup >alist [ dup clear-assoc ] dip (rehash) ;
 
 M: hashtable set-at ( value key hash -- )
-    dup ?grow-hash
-    2dup new-key@
-    [ rot hash-count+ set-nth-pair ]
-    [ rot drop set-nth-pair ] if ;
+    dup ?grow-hash dupd new-key@ set-nth-pair ;
 
 : associate ( value key -- hash )
     2 <hashtable> [ set-at ] keep ;

: reset-hash ( n hash -- )
    swap <hash-array> >>array init-hash ; inline

: (new-key@) ( key array i probe# -- array i empty? )
    [ 3dup swap array-nth ] dip over ((empty)) eq?
    [ 3drop rot drop t ] [
        [ = ] dip swap
        [ drop rot drop f ]
        [ probe (new-key@) ]
        if
    ] if ; inline recursive

: new-key@ ( key hash -- array n empty? )
    array>> 2dup hash@ 0 (new-key@) ; inline

: set-nth-pair ( value key seq n -- )
    2 fixnum+fast [ set-slot ] 2keep
    1 fixnum+fast set-slot ; inline

: hash-count+ ( hash -- )
    [ 1 + ] change-count drop ; inline

: hash-deleted+ ( hash -- )
    [ 1 + ] change-deleted drop ; inline

: (rehash) ( hash alist -- )
    swap [ swapd set-at ] curry assoc-each ; inline

    [ count>> 3 fixnum*fast 1 fixnum+fast ]
    [ array>> length>> ] bi fixnum> ; inline

: grow-hash ( hash -- )
    [ [ >alist ] [ assoc-size 1 + ] bi ] keep
    [ reset-hash ] keep
    swap (rehash) ;

: ?grow-hash ( hash -- )
    dup hash-large? [ grow-hash ] [ drop ] if ; inline

PRIVATE>

