{"size": 2781, "ext": "scrbl", "max_stars_repo_path": "unstable-doc/scribblings/find.scrbl", "max_stars_repo_name": "racket/unstable", "max_stars_repo_stars_event_min_datetime": "2018-08-24T22:01:32.000Z", "max_stars_repo_stars_event_max_datetime": "2018-08-24T22:01:32.000Z", "max_issues_repo_path": "unstable-doc/scribblings/find.scrbl", "max_issues_repo_name": "racket/unstable", "max_issues_repo_issues_event_min_datetime": "2020-06-25T14:58:07.000Z", "max_issues_repo_issues_event_max_datetime": "2020-06-25T19:01:25.000Z", "max_forks_repo_path": "unstable-doc/scribblings/find.scrbl", "max_forks_repo_name": "racket/unstable", "max_forks_repo_forks_event_min_datetime": "2015-01-20T15:40:24.000Z", "max_forks_repo_forks_event_max_datetime": "2018-08-24T22:01:34.000Z"}
{"max_stars_count": 1, "max_issues_count": 2, "max_forks_count": 4, "avg_line_length": 37.08, "max_line_length": 90, "alphanum_fraction": 0.6209996404}
#lang scribble/manual
@(require scribble/eval
          unstable/scribblings/utils
          (for-label unstable/find racket/contract racket/shared racket/base))

@(define the-eval (make-base-eval))
@(the-eval '(require unstable/find racket/shared))

@title[#:tag "find"]{Find}
@unstable[@author+email["Ryan Culpepper" "ryanc@racket-lang.org"]]

@defmodule[unstable/find]

@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 @racket[pred] contained in
@racket[x] (possibly including @racket[x] itself). 

If @racket[stop-on-found?] is true, the children of values satisfying
@racket[pred] are not examined. If @racket[stop] is a procedure, then
the children of values for which @racket[stop] returns true are not
examined (but the values themselves are; @racket[stop] is applied
after @racket[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 @racket[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 @racket[find] on a cyclic graph may
diverge. To do cycle checking yourself, use @racket[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 @racket[find], but only returns the first match. If no
matches are found, @racket[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))
]
}

@close-eval[the-eval]
