#lang scribble/manual @(require scribble/eval "utils.ss" (for-label unstable/find scheme/contract scheme/shared scheme/base)) @title[#:tag "find"]{Find} @(define the-eval (make-base-eval)) @(the-eval '(require unstable/find)) @(the-eval '(require scheme/shared)) @defmodule[unstable/find] @unstable[@author+email["Ryan Culpepper" "ryanc@plt-scheme.org"]] @defproc[(find [pred (-> any/c any/c)] [x any/c] [#:stop-on-found? stop-on-found? any/c #f] [#:stop stop (or/c #f (-> any/c any/c)) #f] [#:get-children get-children (or/c #f (-> any/c (or/c #f list?))) #f]) list?]{ Returns a list of all values satisfying @scheme[pred] contained in @scheme[x] (possibly including @scheme[x] itself). If @scheme[stop-on-found?] is true, the children of values satisfying @scheme[pred] are not examined. If @scheme[stop] is a procedure, then the children of values for which @scheme[stop] returns true are not examined (but the values themselves are; @scheme[stop] is applied after @scheme[pred]). Only the current branch of the search is stopped, not the whole search. The search recurs through pairs, vectors, boxes, and the accessible fields of structures. If @scheme[get-children] is a procedure, it can override the default notion of a value's children by returning a list (if it returns false, the default notion of children is used). No cycle detection is done, so @scheme[find] on a cyclic graph may diverge. To do cycle checking yourself, use @scheme[stop] and a mutable table. @examples[#:eval the-eval (find symbol? '((all work) and (no play))) (find list? '#((all work) and (no play)) #:stop-on-found? #t) (find negative? 100 #:stop-on-found? #t #:get-children (lambda (n) (list (- n 12)))) (find symbol? (shared ([x (cons 'a x)]) x) #:stop (let ([table (make-hasheq)]) (lambda (x) (begin0 (hash-ref table x #f) (hash-set! table x #t))))) ] } @defproc[(find-first [pred (-> any/c any/c)] [x any/c] [#:stop stop (or/c #f (-> any/c any/c)) #f] [#:get-children get-children (or/c #f (-> any/c (or/c #f list?))) #f] [#:default default any/c (lambda () (error ....))]) any/c]{ Like @scheme[find], but only returns the first match. If no matches are found, @scheme[default] is applied as a thunk if it is a procedure or returned otherwise. @examples[#:eval the-eval (find-first symbol? '((all work) and (no play))) (find-first list? '#((all work) and (no play))) (find-first negative? 100 #:get-children (lambda (n) (list (- n 12)))) (find-first symbol? (shared ([x (cons 'a x)]) x)) ] }