{"size": 2436, "ext": "scrbl", "max_stars_repo_path": "log-once/log-once.scrbl", "max_stars_repo_name": "bennn/syntax-parse-example", "max_stars_repo_stars_event_min_datetime": "2017-05-18T22:15:56.000Z", "max_stars_repo_stars_event_max_datetime": "2021-09-17T13:13:05.000Z", "max_issues_repo_path": "log-once/log-once.scrbl", "max_issues_repo_name": "bennn/syntax-parse-example", "max_issues_repo_issues_event_min_datetime": "2017-05-18T22:54:53.000Z", "max_issues_repo_issues_event_max_datetime": "2021-10-19T02:58:50.000Z", "max_forks_repo_path": "log-once/log-once.scrbl", "max_forks_repo_name": "bennn/syntax-parse-example", "max_forks_repo_forks_event_min_datetime": "2017-05-19T14:27:57.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-30T09:36:54.000Z"}
{"max_stars_count": 22, "max_issues_count": 20, "max_forks_count": 6, "avg_line_length": 38.0625, "max_line_length": 130, "alphanum_fraction": 0.60591133}
#lang syntax-parse-example
@require[
  (for-label racket/base (only-in racket/math natural?) syntax/parse syntax-parse-example/log-once/log-once)]

@(define log-once-eval
   (make-base-eval '(require syntax-parse-example/log-once/log-once)))

@title{@tt{log-once}}

@; =============================================================================

@defmodule[syntax-parse-example/log-once/log-once]{}
@stxbee2021["Fictitious-Rotor" 3]

@defproc[(log-once [#:skip-count skip natural? 0]
                   [#:log-count log-count natural? 1]
                   [#:when cond any/c (void)]
                   [#:message msg string? ""]
                   [#:newline newline? boolean? #f]
                   [expr any/c] ...) void?]{
  The purpose of this macro is to print a sample of values within tight loops---rather
  than inundate the console with thousands of lines of irrelevant data.
  It achieves this purpose by providing a variety of tools that can be used to
  constrain what is logged down to what actually interests the observer.

  @examples[#:eval log-once-eval
    (for ([char (in-string "abcdefghijklmnopqrstuvwxyz")])
      (log-once #:skip-count 18
                #:log-count 3
                char))

    (for ([char (in-string "abcdefGhijkLmnopQrstuVwxyz")])
      (log-once #:skip-count 2
                #:when (char-upper-case? char)
                char))
  ]

  The macro replaces patterns of code that would look something like this:

  @racketblock[
    (code:comment "You have to define the variables somewhere where they won't")
    (code:comment " fall out of scope so that the mutations matter")
    (code:comment "You also have to be wary of leaving any of this code lying")
    (code:comment " around once you're finished with debugging")
    (define is-logged #f)
    (define skip-count 0)
    (for ([char (in-string "abcdefGhijkLmnopQrstuVwxyz")])
      (when (and (not is-logged)
                 (char-upper-case? char)
                 (begin
                   (set! skip-count (add1 skip-count))
                   (> skip-count 2)))
        (printf "char = ~s\n" char)
        (set! is-logged #t)))
  ]

  The set of macros have gone through many revisions (@hyperlink["https://github.com/syntax-objects/Summer2021/issues/3" "link"]).
  This iteration makes use of @racket[~?], @racket[~@],
  @racket[syntax-local-lift-expression], and the excellent @racket[...].

  @racketfile{log-once.rkt}

}
