         nip data>> pop*
     ] [
         [ nip data>> pop ]
-        [ data-set-nth ]
+        [ data>> data-set-nth ]
         [ swap sift-up ] 2tri
     ] if ;
 

        pop* drop
    ] if ; inline

M: heap heap-pop
    [ data-first >entry< ] [ heap-pop* ] bi ;

: slurp-heap ( ... heap quot: ( ... value key -- ... ) -- ... )
    [ drop '[ _ heap-empty? ] ]

M: max-heap heap-compare
    drop { entry entry } declare [ key>> ] bi@ before? ; inline

PRIVATE>

: >entry< ( entry -- value key )
    [ value>> ] [ key>> ] bi ; inline

M: heap heap-peek ( heap -- value key )
    data>> first >entry< ;

<PRIVATE

:: sift-down ( heap from to -- )
    heap data>>      :> data
    to data data-nth :> tmp

    to t [ over from > and ] [
        dup up
        dup data data-nth
        dup tmp heap heap-compare [
            rot data data-set-nth t
        ] [
            2drop f
        ] if
    ] while

    tmp swap data data-set-nth ; inline

PRIVATE>

M: heap heap-push*
    [ <entry> dup ] [ data>> data-push ] [ 0 rot sift-down ] tri ;

: heap-push ( value key heap -- )
    heap-push* drop ;
